Merged PR 4025062: New tests for DS and DSA

New tests for DH and DSA

Related work items: #15886191
This commit is contained in:
Niels Ferguson 2019-11-15 23:50:15 +00:00
Родитель 787430d83d
Коммит f2e14c27d3
22 изменённых файлов: 3485 добавлений и 66 удалений

Просмотреть файл

@ -4574,11 +4574,14 @@ PSYMCRYPT_DLGROUP
SYMCRYPT_CALL
SymCryptDlgroupAllocate( UINT32 nBitsOfP, UINT32 nBitsOfQ );
//
// This call allocates a DLGROUP object where the primes P and Q are
// of size nBitsOfP and nBitsOfQ, respectively (L,N parameters in FIPS
// 186-3 specs).
// Allocate a Discrete Logarithm group object suitable for the given sizes.
//
// This call does not initialize the DL group. It should be followed
// nBitsOfP: Maximum number of bits of the field prime P. Specifying a value larger
// than the actual size is allowed, but inefficient.
// nBitsOfQ: Maximum number of bits of the group order Q. Specify the size of Q,
// or 0 if the size of Q is not (yet) known.
//
// This call does not initialize the DLGROUP. It should be followed
// by a call to SymCryptDlgroupGenerate or SymCryptDlgroupSetValue.
//
// nBitsOfQ is allowed to be equal to 0 and signifies that the size of Q
@ -4635,15 +4638,13 @@ SymCryptDlgroupCreate(
UINT32 nBitsOfP,
UINT32 nBitsOfQ );
//
// As always, this call does not initialize the DL group. It should be followed
// Creates a DL group object, but does not initialize it. It must be followed
// by a call to SymCryptDlgroupGenerate or SymCryptDlgroupSetValue.
//
// Requirements:
// - nBitsOfP >= nBitsOfQ
//
// Remarks:
// - The value in nBitsOfQ is allowed to be equal to 0
// (see SymCryptDlgroupAllocate).
// - pbBuffer,cbBuffer: memory buffer to create the object out of. The required size
// can be computed with SymCryptSizeofDlgroupFromBitsizes().
// - nBitsOfP: number of bits of the field prime P.
// - nBitsOfQ: number of bits of the group order Q, or 0 if the size of Q is not (yet) known.
//
VOID
@ -4968,8 +4969,13 @@ SymCryptDlgroupGenerate(
_In_ SYMCRYPT_DLGROUP_FIPS fipsStandard,
_Out_ PSYMCRYPT_DLGROUP pDlgroup );
//
// This function generates all parameters P, Q, G according to the
// standard specified by the fipsStandard argument.
// Generate a Discrete Logarithm Group for use in Diffie-Hellman and DSA.
//
// - hashAlgorithm: Hash algorithm to be used for generating the group (if required by the algorithm)
// - fipsStandard: Which FIPS standard algorithm to use for generating the group.
// - pDlgroup: group object that will be initialized with a newly generated group.
//
// pDlGroup must have been created with SymCryptDlgroupAllocate() or SymCryptDlgroupCreate().
//
// If nBitsOfQ was equal to 0 when the DLGROUP was Allocate-d/Create-d
// (and only in this case), then this function picks a default size
@ -4979,17 +4985,20 @@ SymCryptDlgroupGenerate(
// - If 1024 < nBitsOfP <= 2048 then nBitsOfQ = 256
// - If 2048 < nBitsOfP then nBitsOfQ = 256
//
// If fipsStandard is equal to SYMCRYPT_DLGROUP_FIPS_NONE, then the default
// standard is picked, which is SYMCRYPT_DLGROUP_FIPS_LATEST.
// If fipsStandard == SYMCRYPT_DLGROUP_FIPS_NONE then no FIPS compliance is requested.
// The code defaults to SYMCRYPT_DLGROUP_FIPS_LATEST.
//
// The requirements below address the parameter values after the defaults have been substituted
// for nBitsOfQ and fipsStandard.
//
// Requirements:
// - pDlgroup!=NULL. Otherwise it returns SYMCRYPT_INVALID_ARGUMENT.
//
// - If fipsStandard == SYMCRYPT_DLGROUP_FIPS_186_2, hashAlgorithm MUST be equal to
// NULL. Otherwise the function returns SYMCRYPT_INVALID_ARGUMENT.
// NULL, and nBitsOfQ <= 160 or nBitsOfQ = 0 && nBitsOfP <= 1024.
//
// - If fipsStandard != SYMCRYPT_DLGROUP_FIPS_186_2, then hashAlgorithm MUST NOT be equal
// to NULL. Otherwise the function returns SYMCRYPT_INVALID_ARGUMENT.
// - If fipsStandard == SYMCRYPT_DLGROUP_FIPS_186_3, then hashAlgorithm MUST NOT be equal
// to NULL.
//
// - If nBitsOfHash is the number of bits of the output block of hashAlgorithm,
// it is required that:

Просмотреть файл

@ -1986,44 +1986,44 @@ SymCryptTestTrialdivisionMaxSmallPrime( PCSYMCRYPT_TRIALDIVISION_CONTEXT pContex
// Q primes.
typedef SYMCRYPT_ASYM_ALIGN struct _SYMCRYPT_DLGROUP {
UINT32 cbTotalSize; // Total size of the dl group object
BOOLEAN fHasPrimeQ; // Flag that specifies whether the object has a Q parameter
UINT32 cbTotalSize; // Total size of the dl group object
BOOLEAN fHasPrimeQ; // Flag that specifies whether the object has a Q parameter
UINT32 nBitsOfP; // Number of bits of the value of P (not the object's size)
UINT32 cbPrimeP; // Number of bytes of the value of P (not the object's size), equal to ceil(nBitsOfP/8)
UINT32 nDigitsOfP; // Number of digits of the object of prime P
UINT32 nMaxBitsOfP; // Maximum number of bits of the value of P
UINT32 nBitsOfP; // Number of bits of the value of P (not the object's size)
UINT32 cbPrimeP; // Number of bytes of the value of P (not the object's size), equal to ceil(nBitsOfP/8)
UINT32 nDigitsOfP; // Number of digits of the object of prime P
UINT32 nMaxBitsOfP; // Maximum number of bits of the value of P
UINT32 nBitsOfQ; // Number of bits of the value of Q (not the object's bits)
UINT32 cbPrimeQ; // Number of bytes of the value of Q (not the object's size), equal to ceil(nBitsOfQ/8)
UINT32 nDigitsOfQ; // Number of digits of the object of prime Q
UINT32 nMaxBitsOfQ; // Maximum number of bits of the value of Q
UINT32 nBitsOfQ; // Number of bits of the value of Q (not the object's bits)
UINT32 cbPrimeQ; // Number of bytes of the value of Q (not the object's size), equal to ceil(nBitsOfQ/8)
UINT32 nDigitsOfQ; // Number of digits of the object of prime Q
UINT32 nMaxBitsOfQ; // Maximum number of bits of the value of Q
UINT32 nBitsOfSeed; // Number of bits of the seed used for generation (seedlen in FIPS 186-3)
UINT32 cbSeed; // Number of bytes of the seed, equal to ceil(nBitsOfSeed/8)
UINT32 nBitsOfSeed; // Number of bits of the seed used for generation (seedlen in FIPS 186-3)
UINT32 cbSeed; // Number of bytes of the seed, equal to ceil(nBitsOfSeed/8)
SYMCRYPT_DLGROUP_FIPS eFipsStandard; // Code specifying the FIPS standard used to create the keys. If 0 the group is unverified.
SYMCRYPT_DLGROUP_FIPS eFipsStandard; // Code specifying the FIPS standard used to create the keys. If 0 the group is unverified.
PCSYMCRYPT_HASH pHashAlgorithm; // Hash algorithm used for the generation of parameters
UINT32 dwGenCounter; // Number of iterations used for the generation of parameters
BYTE bIndexGenG; // Index for the generation of generator G (FIPS 186-3) (Always 1 for now)
PCSYMCRYPT_HASH pHashAlgorithm; // Hash algorithm used for the generation of parameters
UINT32 dwGenCounter; // Number of iterations used for the generation of parameters
BYTE bIndexGenG; // Index for the generation of generator G (FIPS 186-3) (Always 1 for now)
PBYTE pbQ; // SYMCRYPT_ASYM_ALIGN'ed buffer that points to the memory allocated for modulus Q
PBYTE pbQ; // SYMCRYPT_ASYM_ALIGN'ed buffer that points to the memory allocated for modulus Q
PSYMCRYPT_MODULUS pmP; // Pointer to the prime P
PSYMCRYPT_MODULUS pmQ; // Pointer to the prime Q
PSYMCRYPT_MODULUS pmP; // Pointer to the prime P
PSYMCRYPT_MODULUS pmQ; // Pointer to the prime Q
PSYMCRYPT_MODELEMENT peG; // Pointer to the generator G
PSYMCRYPT_MODELEMENT peG; // Pointer to the generator G
PBYTE pbSeed; // Buffer that will hold the seed (this is padded at the end so that the entire structure
// has size a multiple of SYMCRYPT_ASYM_ALIGN_VALUE)
PBYTE pbSeed; // Buffer that will hold the seed (this is padded at the end so that the entire structure
// has size a multiple of SYMCRYPT_ASYM_ALIGN_VALUE)
SYMCRYPT_MAGIC_FIELD
SYMCRYPT_MAGIC_FIELD
// P
// Q
// G
// Seed
// P
// Q
// G
// Seed
} SYMCRYPT_DLGROUP;
typedef SYMCRYPT_DLGROUP * PSYMCRYPT_DLGROUP;
typedef const SYMCRYPT_DLGROUP * PCSYMCRYPT_DLGROUP;

Просмотреть файл

@ -845,6 +845,7 @@ SymCryptDlgroupGenerate(
fipsStandard = SYMCRYPT_DLGROUP_FIPS_LATEST;
}
// Numbered comments refer to the steps in the FIPS standard
// 1. Check that L,N is in the list of acceptable pairs
// => Skipped as SymCrypt supports more sizes

Просмотреть файл

@ -573,6 +573,78 @@ public:
SIZE_T *pcbMsg ) = 0;
};
#define DLKEY_MAXKEYSIZE (512) // 4096 bits = 512 bytes. Generating larger groups is too slow for testing
typedef struct _DLGROUP_TESTBLOB {
UINT32 nBitsP; // P = field prime, Q = subgroup order, G = generator
UINT32 cbPrimeP; //
UINT32 cbPrimeQ; // can be 0 if group order is not known
SYMCRYPT_DLGROUP_FIPS fipsStandard; // Which FIPS standard was used to generate this group
PCSYMCRYPT_HASH pHashAlgorithm; // Used for FIPS group generation
UINT32 cbSeed; // FIPS group generation seed
UINT32 genCounter; // FIPS group generation counter
BYTE abPrimeP[DLKEY_MAXKEYSIZE]; // cbPrimeP bytes
BYTE abPrimeQ[DLKEY_MAXKEYSIZE]; // cbPrimeQ bytes (optional)
BYTE abGenG[DLKEY_MAXKEYSIZE]; // cbPrimeP bytes
BYTE abSeed[DLKEY_MAXKEYSIZE]; // cbSeed bytes, cbSeed = 0 or cbSeed = cbPrimeQ
} DLGROUP_TESTBLOB, *PDLGROUP_TESTBLOB;
typedef const DLGROUP_TESTBLOB * PCDLGROUP_TESTBLOB;
typedef struct _DLKEY_TESTBLOB {
PCDLGROUP_TESTBLOB pGroup;
UINT32 cbPrivKey; //
BYTE abPubKey[DLKEY_MAXKEYSIZE]; // cbPrimeP bytes
BYTE abPrivKey[DLKEY_MAXKEYSIZE]; // cbPrivKey bytes
} DLKEY_TESTBLOB, *PDLKEY_TESTBLOB;
typedef const DLKEY_TESTBLOB * PCDLKEY_TESTBLOB;
class DhImplementation: public AlgorithmImplementation
{
public:
DhImplementation() {};
virtual ~DhImplementation() {};
private:
DhImplementation( const DhImplementation & );
VOID operator=( const DhImplementation & );
public:
virtual NTSTATUS setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob ) = 0; // Returns an error if this key can't be handled.
virtual NTSTATUS sharedSecret(
_In_ PCDLKEY_TESTBLOB pcPubkey, // Must be on same group object
_Out_writes_( cbSecret ) PBYTE pbSecret,
SIZE_T cbSecret ) = 0;
};
class DsaImplementation: public AlgorithmImplementation
{
public:
DsaImplementation() {};
virtual ~DsaImplementation() {};
private:
DsaImplementation( const DsaImplementation & );
VOID operator=( const DsaImplementation & );
public:
virtual NTSTATUS setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob ) = 0; // Returns an error if this key can't be handled.
virtual NTSTATUS sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash, // Can be any size, but often = size of Q
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig ) = 0; // cbSig == 2 * cbPrimeQ of group
virtual NTSTATUS verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig ) = 0;
};
// RsaImplementation class is only used for performance measurements of RSA
/*
class RsaImplementation: public AlgorithmImplementation
@ -1169,6 +1241,70 @@ public:
RsaEncImpState<Implementation,Algorithm> state;
};
template< class Implementation, class Algorithm > class DhImpState;
template< class Implementation, class Algorithm>
class DhImp: public DhImplementation
{
public:
DhImp();
virtual ~DhImp();
private:
DhImp( const DhImp & );
VOID operator=( const DhImp & );
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual NTSTATUS setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob );
virtual NTSTATUS sharedSecret(
_In_ PCDLKEY_TESTBLOB pcPubkey,
_Out_writes_( cbSecret ) PBYTE pbSecret,
SIZE_T cbSecret );
DhImpState<Implementation,Algorithm> state;
};
template< class Implementation, class Algorithm > class DsaImpState;
template< class Implementation, class Algorithm>
class DsaImp: public DsaImplementation
{
public:
DsaImp();
virtual ~DsaImp();
private:
DsaImp( const DsaImp & );
VOID operator=( const DsaImp & );
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual NTSTATUS setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob ); // Returns an error if this key can't be handled.
virtual NTSTATUS sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash, // Can be any size, but often = size of Q
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig ); // cbSig == cbModulus of group
virtual NTSTATUS verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig );
DsaImpState<Implementation,Algorithm> state;
};
template< class Implementation, class Algorithm>
class EccImp: public EccImplementation
@ -1321,6 +1457,20 @@ const String RsaEncImp<Imp,Alg>::s_algName = Alg::name;
template< class Imp, class Alg>
const String RsaEncImp<Imp,Alg>::s_modeName;
template< class Imp, class Alg>
const String DhImp<Imp,Alg>::s_impName = Imp::name;
template< class Imp, class Alg>
const String DhImp<Imp,Alg>::s_algName = Alg::name;
template< class Imp, class Alg>
const String DhImp<Imp,Alg>::s_modeName;
template< class Imp, class Alg>
const String DsaImp<Imp,Alg>::s_impName = Imp::name;
template< class Imp, class Alg>
const String DsaImp<Imp,Alg>::s_algName = Alg::name;
template< class Imp, class Alg>
const String DsaImp<Imp,Alg>::s_modeName;
//
// Template declaration for performance functions (for those implementations that wish to use them)
//

Просмотреть файл

@ -158,4 +158,16 @@ public:
BCRYPT_KEY_HANDLE hKey;
};
template<>
class DhImpState<ImpCng, AlgDh> {
public:
BCRYPT_KEY_HANDLE hKey;
};
template<>
class DsaImpState<ImpCng, AlgDsa> {
public:
BCRYPT_KEY_HANDLE hKey;
UINT32 cbP;
UINT32 cbQ;
};

Просмотреть файл

@ -25,3 +25,9 @@ public:
SIZE_T cbKey; // Size of modulus
RSA_PRIVATE_KEY key;
};
template<>
class DhImpState<ImpMsBignum, AlgDh> {
public:
// TBD;
};

Просмотреть файл

@ -302,3 +302,17 @@ class RsaEncImpState<ImpSc, AlgRsaEncOaep> {
public:
PSYMCRYPT_RSAKEY pKey;
};
template<>
class DhImpState<ImpSc, AlgDh> {
public:
PSYMCRYPT_DLGROUP pGroup;
PSYMCRYPT_DLKEY pKey;
};
template<>
class DsaImpState<ImpSc, AlgDsa> {
public:
PSYMCRYPT_DLGROUP pGroup;
PSYMCRYPT_DLKEY pKey;
};

Просмотреть файл

@ -839,6 +839,11 @@ public:
const static char * name;
};
class AlgDsa{
public:
const static char * name;
};
class AlgEcurveAllocate{
public:
const static char * name;
@ -1118,6 +1123,12 @@ testRsaSignAlgorithms();
VOID
testRsaEncAlgorithms();
VOID
testDhAlgorithms();
VOID
testDsaAlgorithms();
KatData *
getCustomResource( _In_ PSTR resourceName, _In_ PSTR resourceType );
@ -1627,6 +1638,10 @@ runRsaAverageKeyGenPerf();
extern RSAKEY_TESTBLOB g_RsaTestKeyBlobs[ MAX_RSA_TESTKEYS ];
extern UINT32 g_nRsaTestKeyBlobs;
#define MAX_TEST_DLGROUPS (50)
extern DLGROUP_TESTBLOB g_DlGroup[ MAX_TEST_DLGROUPS ];
extern UINT32 g_nDlgroups;
VOID
fprintHex( FILE * f, PCBYTE pbData, SIZE_T cbData );
@ -1640,3 +1655,15 @@ rsaTestKeyRandom();
PSYMCRYPT_RSAKEY
rsaTestKeyForSize( SIZE_T nBits );
PCDLGROUP_TESTBLOB
dlgroupForSize( SIZE_T nBits );
VOID generateDlGroups();
PSYMCRYPT_DLGROUP
dlgroupObjectFromTestBlob( PCDLGROUP_TESTBLOB pBlob ); // Must free object after use
VOID
ReverseMemCopy( PBYTE pbDst, PCBYTE pbSrc, SIZE_T cbSrc );

459
unittest/kat_dh.dat Normal file
Просмотреть файл

@ -0,0 +1,459 @@
#
# DO NOT EDIT: Generated test vectors for DH
#
[Dh]
P = 8129643cdb3e7d4cc081166a76fe09f9b42095e102c5fd3015cd151f637d581eb49a3c9d634de951d787b65d37081f955720f2f0f3a701dc832c4e0093fcf57df778dd99995038beaec169ac08cc1f389344359c9785f65ffdeca56cd3e4d15601a5c804b682aad0be6a848931962bbafa731e1f434502c260f88296b722fb4eecfbd476f3f0a9c854fe5a5996e62c5d96f4fbb1d607c35b6455a1b396e9dc89a712c4de0f36394704b51f8fb4e0323697b628da469608c6cda7b6abb501ac5fee7f454d1547ce8e4b565fd7e6bbc7b454dccdf683b1cf0abcff2d51269968da3e4bcdd29083f015915a456b089c7db608d4a796226d90b8304607d3253ad94a0fbb414088ffab9065dc728d519937b88ad0c7089aa9ba3e46ad5e264ef154dfe3db956aa552ad11fab48e34be6fe1f424dd32aa8a497b1c3fbbd91d95a1fadb28166f44751b4d1a312047bd92c5ca2e0f609bfc75bfe8514553afb4260680601b5a954918c19d5a7efee37e38880b00a3324a51544d91df414fedce57795e8be7c9e39c0405ce7b07ad7a68726ecc4da76bbf7da3c048000410e60b055fe19fc413a45e6d7c07d4a99cdee3e756aff572612ab0119efa94e9ae5ce923abfb2396efce36aa98133dc651242db59a40e2ec27478e996920ab0e4fcab653774fd30d5893496a05de34b235cedc26895459bf7a2143a445bd9ebb8daaef177d36d5
G = 746bf0db7b92751f05521ba953846b6ddb33f0de2eaa4ddfcb114994e5b86c3a326cf10dd4dfde97fa9142ff81661f0700c20fd9daf922be43e25a24db0500ac9285af3aa20abb64a60a921eaea303b0b8af507341908534124ce297781cdce7b71bf639b0a8664d049812284427591ca37eb9c335711ca88f4bba9ee8ae0b9dbbaacf9b02744bf5aa73004a6ee387f6552acd067bbb22a517113917fecf9eb74d05a3ad9e527b8c0438908d0545ebf795ce2efd4081d95aa6900881890deea0c8f2448e6c01c0d6991c7e49ea2f93524b2d34fb057018bc1bf440313e5b9208b7bf5c7a74eb5d1d83ff471b7d29bcde19c97014bdd75aa6f40aba4d856caf9d1a511d2d381a30986b7d07df4150d48806979fe214a6c7a858f2d7ecda450cda61b03146f8c1d5f436256601f3c5c7c20087f02adeb35b9ed36491f6ffd166a9b18d27c0a9227bf7620017c2ef7c8a34b44a6e35842203dffa1a1c99e1754e4a4b0222899b764e0faebaa2bf34102ca9cbcfcc55a77145355da3ebe4af6f66ad9005c4e0e6288ffe423942230d08fd5cfc3dc39d9292c0426bfd3366dcf6feb14350799cb82efdb5a5fccd3c8c65fa2f85c8ac38ceb2561271045d5156b14112f3aafa084ca620afdd34959d315b702ad7cc9b5d14f48a0af5ebe50fcb47d34f6a7986eb8af9ab616e9e467460525372a12304950410528cd4c08484a469ff0d
Q = bb956ecc04c1a5a4a130f5eeb52861d13fc6085fae74a97bb9c04152dd2c84a7
X1 = 0565792be96e6cf5efbfcd38c6e78a2ce750a8f96e515fb8479744df40efc845
H1 = 4ffa90945916ab45dbd05ac164155fb774f4b6669a1187e818f5a39928631e1ec53932f697bc6f1b4df6d339b0e54eec9d232eea01caa3fb90cb42bf361020392db4b25ec4973e98c3b5f89e61cecd12fe1ee2c08c74768b971dc9928b9704971ee7febb02fc3b4bae8e9545e5771d9efb7581e0589a908928c68474a531c13fcfa7015a05e060b460f2ab5848a430064dfe537d86f197445af6b79e24bb437c76859f1c1e53a2f52b4085d636a21a7159450d018e65ccecd35cc0eec5b2c4b33eceb018ad5c4f6d43687c12eb991776c28e93820da9e6d8a5f6f563878e2ba53d3640346dcaa6ee0b7f3d3b6b796576726717a6effe7fedf9e94d15b05e44a328aed5d5f111691efccecc556fb50a3e6bca170a3bffe2e0ca4b57c73ecaa90a3ce8f0403a2c6cb15888b156ea78fee2311c1175d58ca3cf89a43125c2e2449a3398f4e5c3e6dc3ed63507b26764c84a662ef30e24898ce39ac7febc37e5bf0ea32d56027b86a52db79dec92d0cf47bd4cae6ecc4869e8682f2882103789b2fb350dd506876b3b9f0370f277d87d8aa3b9be8a170a0c41e17c9694f45a2c7593bd02034a3513d26835aa8cfbf60d2c44103ece3a8cd7b5b7a5959ed06d883cdd991b6fd6ee8db382f98dade3660f786ba41b0da45ee74f2c6b630f9b9e9690b7ca9f5c1017f71ec87261fde424be8ab8d6aa75953dd0174454dad4c7f87cc8a4
X2 = 75dc8adbf8f1e9ac642ebb0f7ae0f636f224238178ef8d8d67af64bec37ae39b
H2 = 50bd56b3df9aeb8cf645458ad6bab3c946158c1a6e874f43c3b2eaafc62c8a89fab94448f2a26531735e51fe65e85ae5c61252fa2a83778e343bc25d525807ed93352e273761e78f136f88be90dba10c626ec6475a22a053c5abfde1fab16f9821a2e754fd2cb5226b09f0a70fcb3436602f374a83148593d78ea9cd2e31810090995fdef5a2212113c92297e4c227bad8d7d73727dd18f267269fbb554f8df1f9973e048a55b7febfb7bc041d1b373679fc13fcdb2a016f4b95fb2870ec71f5d20e07ebeaa07775122adc4b349a4bc0a734db34f71e1aab484ea0874a3655698daea9a4ce8175470d366c9f36a8017a90383485ced56560f51e176e2a5975492fdff4cdd4e5345db8dd4bd8d99c1c74873b45d156fcac3deec327b205b61ae05bcdb1557a36e443e11379a3ace64b0a2c7fe8a9b480a573499abffdb7f986b690ae9712e6f19fdafa5da1d55d3d9f3823e37acd34a4e60ef9915d2e18b12404f7a2a877676e20f7f5e89596e7ddeb71ef7a848128d96d04e3e2aeb1160ede216345196425ac864e59271cfd51237e73839ea5508faaedb33db89309585be096d51e489c79d2e5bae30443d8f129099d0e25146b866d5695bb02ff717c3200b9af5441ed539216f87f726b3475a07ac2106e2b7b8751b7efd44690105e8813597039844e9c66c45dd51a555e53193089b5879d79e9eb9ae010b452eccbb3b316
SS = 4626f0870fedfecf7eea51991f5a4dea1db72d6e023e09b7548234c0a2ef3014f46c9b555de4419da8c562fdfa5b22fa2bd545d2fed02d7ba9a70a386d0eb69edd467b25cf6ce92e53f5ae31d2de12e8116d581af94a3b86e3c7056ae7d1d3e9cba9612222fc3421662076d0e23ffee57a8b1cf1b72659176c822be73f947be718aaf96d391e98f0df91de0d594de3726e6e25d6a8a1187cc9e0e45acc58e35047681b9b481bbe56b3c2d8f6a0438aab92b80a37cefefde6dc51797a89f72f09aed17b01c0b7475505d901910011274cc0e2acb8975a72d3d22b9cb32f3275049fe10f15d3a8791a8d402cd5f5ba66fd81224a767bfb8ba39f56b7526bb1a8bbef4352b23d07ba78f59f0a2729f6a47ec6810d916d4a0ae4fde3d26850d521219efd284e499dabc6a8fb03addec6d9eebd38f722a6a332fe66efdcd00757dc8e6c4ad84298cb2eb30f9ddaa04ce11b2eb9c5348282f1657210f6bfc0b2d902b025df9d861a05e51f725fa05381f8180245f648a142f6624bd791b5713f5a554575e4618a484db87e0ed04441f2ad407c195eeac407204d1aee72a6a1443d82ccf890c126f74b7e93eda0912036bc5cc880299428b495d0b0694bb2f99e07d3db6266ad3c87836a2998e8a773fe69dd6cd5e858b5f1bdfd826eb7883b686c6be5fc11ba1777fa4a5fb09fcfeb1835eab51bc2263acf57de927b035b500177e31c
P = bbea4e0aff14f521a660ec70aa92ed22ef7819aab9cbbc2446d3a5624fe5cc83fbfa2aba3c540db0f67e9df02a006cb8787e54c84baa9730f53b36b27b6ec2f28e75bceb66bae418d765c8395de8601e53448392e6dbdaa5d313a481d2deba644ba95f80693415b673c1720fc2a0b2bf4fe99a9d262135e39287e27f41d6a3a9f2334e357ed03e9e245fcb4a77db07deee807524d35bdeef0226dbe7198dc178ea98648dbcd17899945c6b1759dcbef423c2e6b612545acb4c119f20d7f8f26d2df657ba50f78d1d0357ef16c736c5498de07806ac6e43fcef4e68ea674221f13f5f70891e7a6161ab89104c272f4748a0d5ebadea0b2fe36df5ac97b9cdfa49dc6e9c8cbcb32921a7cd15afdb122ba10a44f4ee8476de0581013fdb0060f3c77215488b9560eeb47733a28049b433dda38c229a46ffc8b85daedd10a00b950eb26393ccc05dd08c8f4d29e4373448bc1882cd74396b80dd1aabef00f90c8512880fee85a4e946a673cba8707e3c231a8a50e74323f44af2c04822a7b72a2b79
G = 03ffb1de216bfa99f56cb76310032b973bd9a4633f9e7500e5d57c9567da206c5552de1c715889c8ef9a7c5ef5fdce30fe7e2605987aa883526b5edc499a9f93aaddb77ba76513893ece04410eed23dbbfdb476a3a6b5f10e3b6abca168e34d4899a4b64c5b1be062db2406f4367534057b83a382b1814feecd277461e2aab648fbffad821606820b80742423ba671d3ade04524ec8e7f5608fbd0c37574cd542011e3937c8e750ca6954f3f8a94652dd2390f06d62c029945e00db404705eda99d0ce9fe5926892c65c91695ab8a4656fd87f06ee4405b61831fc6ce9695723629150fc2e2b7de0c6866ad4288a2dffc255cb3742790cc3ba906a164c1ff93a253838c19040c6da8ea4156383ff46469b5da5b30e012ff3a5b64ae1ab938d67c8e355a6f0208a5f8b1e3066b063c8bc83c51fa4d1615d6d403b62d502963c95b48e6c7c9b8713994eb9b469709b0c75e58a4c3d96cdc2808a2a696c91f05aa4c6454f58f09f90e193b85e4049600ea77ce7f27074cd553d603f2a82b3385ff9
Q = f07a2ad7a2cd0e2cfe894c85252c43ef42bc7f4c8e7e0dfd69a5ff286bde3193
X1 = a92f542aad5af34d184591bd83bf1012bafb0b50506487377c28d3c5519bff74
H1 = af5bfdd64dca320d5ef77a62f44f8b0e5bc3f80a349db77ac7612a9cede0666230ac2e04d76b641f5101fe32ddf133aadb26c4006a5006065ea919eb6e52338d5e0fc4ddf6c99189d1d307f0a24a6a999f3c5218326c9c0de0bb7bd2f56734127587eac83ddede8834a25ae7c8adcefcbbb6f9f432ade99b8924e09d619a6e964aafe3571d5773bef8a3a2ca350c8dff243cbe5dc5b147bdf410af9b10c2ae31af4fa762b16c5800c06ad88d31e76885b7926e962f847f668f97b772f223fe38925967d705534e9820a2b9dd987e63c53f899eb0b4f908c8c92654abbcd8c5f093d826bec3a93457e7bb300088d9be3b8ec7594596e9e404a6c8d47cc201932e669f86320465d220469a3859a7a34198d668a9a3c344ed48ce91210b2e59695968b8f3d755b2ce0d944b0016ec4b9eee7ef815134c338c1ac36d70ad81ced53b1f27bb90cde07c97e58ddfab44e0a0b8a55652227ac48d2ffa817688bf0b6aeb1b94ea7e828cc134675e00889d7b6e74cafd94755c8e3bc570dccb440f58f61c
X2 = 9529b7f8f46de7479245ec52c4019fe81b5273f3b7d094f48addb75722785f11
H2 = 8871b6b65d8134f4470aca092ccada58ccbe5893767d07fdfb86b809dbadc3c4dafbeb3ae51cdbc950f2549fd6366a523c6eb5cd2aa7342914ee43caf68a8969bd4f7cb171ccad742dd452688e38d0431e456a1aab9fe32515d8d66e0693abf17ad00b8994c9ad270cf6b94241219519cee0f4f38cc883ae0efc9c930d7cf18c5f9ea5c0bc80afc7a997cebead0d48842e477d6d13f8b482e3448311a7abcfb661af8c9b5f9e8bc73af47629b03e68ea940397981534bdd2fc04390ea249c8e395eea27c8a86be572d418a5cebc37e67378b6c0ca4fd29298248e6745d47ecdc5605a37341b89e232e42dd07344ef02aa169b719d3d29fee52ebc38263aaea2d6bd80998032ba1b5934e53626b31b2b93e86eecb89eff8bf201e62cf1cab012422be6ecaa7ddfe4084da10243cda86d7740336e997759ae9a47cf9f2158363bd256b1483b16d4953134032f0f3e970b0835c5004831cb8ef6cbe8808ba13981ee5d407a0154ab510b40e31e5f47727caddc7f6e1602e6b7b261b202367f3a25d
SS = 2cded53180b29fe86aa963059645334d3a5a1608a41beeab11c1207014f71daa61414a505f2ae8ee146e119807dab2af7c45980bfd69f1f42389fd6af0a04162d3c52b6f233d36418d09c4c0348f05db8c098a09e91fe7edcef752024cb5446563515ff7cd8da2bafcce71774af9649fd3db4e8fca44112891cd70b8eab8df8471a21b79a9e8f7e14702159da3c50a3291e5db3163db770e1900112d2fcc25942b5ae3ceec4a40f24c1d714a8eb2ac545a78e1c6db45150377558530aec99cd7c88e884002f5d2e44802cdef2fe324940476bcf409ccbc3b46fa2dd537c7ec6d8e42f2ed33809281de06e1a1aea8f58747fb6629d22bf5e4f1049fb84e33808752152d941ed40140aff1329496127c08ef40f2ae141d1db7c754b9362185b237fd79f16208f191d6b65082275846dbb736c5eee0bbc04831625baaa6769e6ba13d11489dcdafd24879d371546c3854c9297b10aa4aa07b34ccf9a69f28d98e8b22c09a98a37758ff5d8d33636e5235826e2c69fbee2268091969430f9bc72e39
P = 9be39d1315de266e1bf9100c2b878ffb3a44dc5246185575e004812ea6d583454457e23b9bfa39b75f231de6aa90ed189c22991ae1b8fc8ef2170e6f15ee54c0db4d8cb628b6aea790208edb5c85160d04e6389e5f93bc74a419d1b68dee279a54c65f4a0428393c98a954f4384fd65ab2c3c331b323e20eadd9a1eb7eaf47b94c77380e9cccaad966e55568b2ca025a272a12bdeaa501dcb2fcc821be554c453292522c33766edf8537a084189f8ddfe9b4f50032145f328c3cf2cf263958f3eb59646ded2b567ead1d1608881ff272724c5b4e4534e88543e5605327162901a9a369cc1ffe5fcfc7264bbaa3bf0429ea1a4a89c27da0644911d292b05dea189c557c5a90de53ef3c4669f08a5bdca8946ed9c642cebbd60024ef7ae7b5cab11358bf810c4d842d4a4b2a0ceea85c7158df7800fc2c816407ec5fd45c4eaa26f873ed5f4b481253b988e10041d78087970011a1a9d31863a66f888ff1f45cc62801498c7642f0eac7a2438fa0e007864aa031bdacb087036eb0fc2cc409e8b5
G = 831f5b3f5d4d69daf1713f9342ae7a89b0c13994bdc47b1214d1b1122b0fe4f0d0a0b165f4e45a6834d8e04bd7757df9ce84aeb5be195842a14ec127f319b519641772135b2a84b9838acded76c67984526e89133248f7fd41f14c4724b0e83a62a9731d2531b5b0008e746ca36abbf67bc2ec0e8e657e33e2e4e0297d8856a30e6182676121fc614aada4c9a536a917aa2d664963d58400a342741fbeac05781cf7b84f49b834b91644568c1fec6223cbb06a30a775f5e7d2b245fd89a9e99fa9dddefa3caa164f8fe408d4fb79e48a7368a865555898a6f81256d1a1bef36698bbd1acfb975098924371e1a71c88874d885bce16f72c0f41106390af12ce9983f9050c9f82758d93d48626980131388bd050161d426be84f1aa61ec85d2621a3fee9f10ae9082f185fad5308c5251e1169de5546bb036e668cb0cd13e81c4d625f802614f0d9559f55b65c57e099be90151d594ef82ddde2cd0187545de00e66d3d6b923f4b5009b78371ce6b3ed6fec95f27c66ae9a85a2fa4acce9636f63
Q = f1941d783bed0eac51c2df7cd600514c7e812454eef306317ee70ef86fd77f5b
X1 = 9d0d13ea41dfa8866f2f41a22ee517982d9663b6a7f7b7f78d6682c1e890ad30
H1 = 45a33b424ce21fc1e60c36d3b632e639dffe02d41522db0fd103f5a7038bd620d0e7ee2aa741ba7abb6d4cbefed77ebea52fe6860bb67952e0600595b0f47396749277a980cd1827f0501f59c0ffe2ee0ef0d73d18cd03d8b764f54b6965f038af4b4f1b43bab9fdc8e98488cd31b7734941cbfd66cda1bba7ac489009e7435a0d7d025380c7f24abda953b955d728f749fc21868185977a5a5bcd4614c4a6ecdc53ca32d87f3abb2ebef379ca9aab7a35771a6949c2d9bb85e6494700570d9c14c0fc114fc781614ca50a9689fc3492e2a4a0c81ee4d82a93dac08c97840af99dd64fe254f92974d2aeead024781654ad93da9f751986fe1aa541c9ae5c80c03014a90c08f9e35eca8e51b8f10760e157c8d49883ac99f7904d52ccef767f5e9f47e779e6903f0e9fd81b147ddb683c36b0293a8a542b8852a9ed4dd6f56a5410c6c56384225687a27b3b04e011aa9c557b03e4d95f16afeda30023ffaa44f9148c42e4af9b7e5a9b92178739fba218c7d13fb532401732c676f8881908b974
X2 = d05d83d5f001968669cb9b1adbfdfac9d129c1109b5d1bc52761b836b699cbc4
H2 = 4171324787e22a1de9ff485b6c56ea4614388677cee7cf3bb18b94766bd4293e6019983c8950ebbd33cd9b1ab092987680e350eb650e4e00513a1aae0ed3b3d6a10400947970f0b581a79ffa6fc3effc4014d66800d4f01bb07cf51edd7108ba4b71c5f74424c0c4ecc18147a096b2ad3620c7ecc772837655199fa21a1a9b74af05e0d9f5af6e1d2d606e8bcf03617c1575c86b51d782ecfd9c539abc05a170e8788fafd0b24ad5a39ac114bccf30a6c6e300bc98b7404884402a7a2b02ac6473fab281a35f11bea8b6f96a5db27efad5f095f8cc34326c4a1af86d6ddc4ffb6a2d199fc3e17a08a18afd00b636569600e0f5ada64937081535ae408ff2678ff1c6708618f8637590961a7c7eb68c32d5efb5a66eb563321df2662b59bba368be0612458044c839ae464b57139a17ce0a155ec4930560ccc675ad063671c20541f9ebd787d8ba8bba260f17e056e03b263224f85bcfb710c38326855b53612f072857dcc337481f6f07d07e7e9e9ac061c6b06e405ee118094b48beaabc4a0a
SS = 8c99f945be830f9223b582fb742cbb231822d09d59d82b6d43951cf73bf8775f0b7fdb9db8685f209d3474d562b3131c50a5bd6120dfd527cd1719a15e04f5373fefd66ad6a5f2998014495d2b61dd30c441f28521e4634bd85c5f59c1aefd0d4405a1c1ee9f1f28f34b91d0d031e8c9fef0b88fdd4f4048cc29550b3f96904559075ef92998a1eb33a5f59f657cef33665c3226b2208f0836c42e19fa2a9932dc2d4e1913ae5a6a1a21519242f5d629beb7ec956c837afaf6885c115e2407aaad13acd15855e26d17545b0d797e2b9a79ed8bcc9a8d554c7a150e0aecb04244239799ba606d25704e89e5af4c5ad0ecceb64c6877d206c12c901fc30e48bc9e226c4a071bf9d403d8d247c32f982b248d2f0fb4f6bb2bbed7e015ef03ac96efd1428ace8879ca601669a4ab27e26b59bc08e316943b0f4083dd479afcc7688084e79053edbb822942497c4c4343b17956f5a9f8c2f969bb096c7955e8b3994fc7448effcb9ea4d98f148280a5cf7a1149d82118576b20c74bd03875d25568f6
P = eb5f553740160bb23cba5200ab3e679f9aa0a166aafac92d89b5a7d61381e92b8d180dceba4eb47b81a75cfb5515a1310475c4fa3bd2567c546f92c9df29353e0289fd594735d2c22e0b911db7b6176463b948f901ecb6b3fa281d14ec2e845b30beb18f81bec8fd2bce8c4ccdce611bde8eacc95b36036cc4d88d71a70e46a1d38ed5f323a0bdbbd38cfdd8edae56dc1562ed85ead5796110d7f94c51345ca3f0225f6f26b390eb524109bee86687a1665c813aa09508719408708daaa12aa00fc81d698bf1b7c372879ad7d561f18aa4c387ce6b7b6fb9b0ad796cb1918428c588281f819c58914f5cf0c8d09180c5649fc73437c2272bf89a3f406721a7e5
G = d52b821ced761372a00f2dab4a19f2d62e27425946d2db52acea9c5b2576ad3da23ea95f9ffdf776d1573cc40b52a384090b2f5073aa33e8410da274222041e40e00260089ba237d129894647221b1d77d1be03a53572e0069b7d61edf39ccb8ee276634fafdb4d7a25a83c3d3b66eaa8387be350e25c73f142d841e1b8329275c53e9caefd54d6ecc806a512ad5580ff044700bc95b78af369069046b023ac04c9bd19f76ce750305b2b6f15586fd960c78932469eea7de8264b27a39921762a89e26376a47e5d496aa331f21144907ca3520834c641df445d2de4538a4c1bf92a4824fb0e6ed807a12e461344a291eb4910512084de31c2ebe5a34bd1443e6
Q = d6a06a0439513794a703bdd9e13bc136d1be925887b7f67153bfa4b17e2cde25
X1 = 3da5de272c8765329ddd14e912cbf925fb8e7387b9c2cdd11d1627fb92223cdf
H1 = 967206f0236aaa81c3c601a5b9b58521682483cec8c95c590820ffda5e34200fe2b7d79ca9b0d1d5a121e7b03dd4a970bcfa0592bdb8a038730de4b28f859cc534b25f4ef81350bbf1f64da934d88521e3be5cf1b44d7f8ed168220b1984622b1be6534e996a77ade841fbc17820274117a99e9522db0c6a0d4123366d35c884f5fb950989cd53136ea2225b9708ecf4a60a76c947bb3670a1f07ba35e5a617398d9ccbe3fd59f50143a9901a333823fbbbf22d67f9e8246b6e72db3812da9317c568969bbb7ef89b77c3e36bbd9b53236667ad4ebeb1f8fbf3209f98a3a465c4122d630f67697b539265a4e7056d3d838858b77f7883e1a1c6f204993f68e29
X2 = 0fe213e3e08932632cbeec9f541bf26c51450e69e80823bc78a0ac2a024b726f
H2 = be9a9a03f13665b20bad6b17a0cf735f1a0919b9cdb3561ea8c070eebf6a9fe3907b12c613fc819a1d1c6b6b0f5a1758a4facf265f56ec9afc84a1be05a391d0863f4f2825e808d06733ad8ca9f31476d250de16d357c6fbdc6e30db1813e4e8f7ef00adae152b898e508bf99348aeae6752801db5c946a2d3146228e44b42e87dcf0d0635ab55243f2cd547b446e07eb28a2e34faaae397fba39ffde6858b44404ee6f51c08d4da639ceb4108038c1087b1797bf5ab0b5b32fd8101aed579f574a6269a8d0b0e75923d2b499b965c5e9259806631923ab74f2b124156a61641efbc4e34812c3f5a4da7fba193780441f2ddafab0e8e5d2f56baf5c6a3900fcd
SS = 1af59d011ed7e71096a2d8836a312d26b165841a5abe0e8dd3a6d1e226c9eaf8245192e9a0c734dcce304a08fd357f0e5ea8b56e862467dee1a1c7ea73ee70ed12cdb78e2b5261b59de6874d57293a3bafc7735097724a238956a9793c58c7b6c42210290aa1d3c4af55a5fe31790fafbfc3537551f911dce1d6b59e48e89b1415a438d04564e1a7214b14c9d03f38b1907cbe7b202238b43ba3ace05fce9ac78248ca313a23ab8cef1f95d8d17d6599de3cdf2f53b3e2143fb432cf3f2ff93b5b5f838c7629ee24afa6f00ff990af6e7068ae3df3ce92099d61931903f616eb83dd77b64cb14b44b92eb50919a969273c997c58cab7cf0c85e35899a13a4a01
P = 83800cff7d16ff551eb8ce7d3b6db41b99537191e0b5668f5770a8e3110bd005df598be894451dee3c8187fcf0f7cfedab7e74689d01baa783b47740746305df3f25895bb6c8d6273d41597d12cca87b69e98ee4b4a8b9bf22e9be432bf24e99907017bf7c281f230d71bc14eb5f61b4d3c56a8e219cd227276a606c2e052cb4f4fd4d08ddfa14c447f2d0a6784687dc79e5a17fdf6a56194628a892510d36969524ab1aa7e7300bfca82d67c0215b7fc9ce058a8e5d9796f74c6c0e49b017c37850025f13fbb8105935fbf1d3e43086a9d4e97241bc79d04da29e27c12b94ebb180df1acabfe22e33636903f530dedf39003218ee5c4c094369f165ba8fec1d
G = 5126a9721817cd6152c814ff3b82e1f0e9f02b3b9b3123a6c8d68939a820cb723e76c3a9d3c1a05e1afa0247e072f5cba9bab1a8840439f388b1b904af5598ca14525579ee24b661b9efa9aee78027e273a3d25d9419b827047f566f9d5e853af943e28164c1780504166f8bbb98782d62c32f0f735435359714bf36369472a8ebd85c25b4c86de9952507495cb351dc7ecfed5771222d9d8f9b941a26a33464572d32a1bdb8a29876f18e812be11f1a47f3e0c4fbec8896aece9c2dda2cfc4998d2ad59489a417198dbd5d2958ffade2f72f6e2b76ea4258302e3737e04a377d5ca5c5eff74eca0f87f3e34a6bb485191bbd2aa70153a327e50749732cabda3
Q = 8f4040f1c28b55684d0d1873f6a40c16c31408e0dc34da2d8aca00f105af1b55
X1 = 462ff1c3751c7a07bbe9c3a8d7434a64e1c89fef5cd54e6ebbd3c40a46ec751b
H1 = 7b305a102cc7ff583a114c910b4725f869e6c45f4d1b43615d66ec110e2592cafa5dfdd9db725ee15ba81e705d2795287083324f125ad085b0c54e6b0a35423ee1d147a58b642e0fe920f4437a2222306036106e320834724c06aa15a513fde6ca3b5578f539f84314ef2ff7bbcaa0a78f62f198017a7fb335d470f386b6172f244046941940f6f4e247c2984097c92658107584f2058ce9cd026954ec57f7d9bfeeb4f68a993c8de7d86bbff0db4056eef36e1a703ceea92680b7b768ee474c85b81912c20fd127bd17d8864cafceb3444150f569f883e2b2615e5bfde2c3ecb64649fca758947c688f6c1e20976842475a8f4f08c6a9c5dd3f771851d43d95
X2 = 35697c7ec9b876368dcece865741b75868cbf30f3d548d9106255a19a92e8665
H2 = 0ffe2ddc618e57264fe0a82462c3f74f8d48ec0998d5fac01a13e02c2dfdb2023134cf3e1c10ac5d649cef892a117a7b0a2957fb6edd63d47596a3f9e6af961cf0bce771cbcf78ab8a6fef8d2b094c3b89fd2882a618a130a20bb069bec6004ee5647d1dc721ca096e12bed5e438b7549da83081975bbea83d05b91373290723f3df0084cea6884bc173adc45d1d4853444850aea84c6987295af7a19fd4825d845fc6d32b0c429131e31acb0333a786213b8e509acf2b55090e96f3f43f18904eb482153dec21bf4063c8650d08e5c115e547f8ac89514480d9084bca0a52fd1e231cb541cf1a527efe10c14846c41fcba43bb794e3a0b1d9d5bc06d2fc7bb4
SS = 72955484872e23bfb0a6b8affc9422c26e0c41d6522fdc500db2d2d0ea115286bd0505a333ebfad04d7cfce30b54bde2f80c080927399cb4542fdd782fe4cb2c4d062fad1dcadfdb80003bb0eddb7c0fae8bd320cfcf2184173928d705afee92f9f6d08a072b91ef998167191a9b5ee53251b4ea9932658d47e634e8cdbe23a4dc6983bc5e24d42cc60573e791c7c0a12aeb9a871e912a12625e1688bef3ca0a40002766a17279b0e227910dce6053973f7af061443fdda213ff8d50eb8444a8fe9380d7441eb76861188065451df1533e5036419021eee5cb2c3164b1e7d4a31f1c2be43a79aae5fffb110080caf96670695a622a6ead4e0a3af1251c841e6c
P = a994f44d036154af7121815ed409b543a282aca30bb682352443bc19850481e1f9d2cbc9afac40c031239498935d115ff5c6b54bb0eb55c4b0f2762e368a8cc8fe83495d76bec7ea428f264f47930bab6a67f8e77d25ed38713a6427edd5ba6e171acee79cde953b453ed22a6ac9116050fba5ff58bf851be108d41aa83374d462430e601704af5bbf22299e5d95c451481a94a1e6b6f110ae89eaa47cbe97750ee77ea841fa37c7bcc956222f12201076e0fdd1b0b83d092faf44e617a936d2c01fb27d4f1816ec7a96cace2d7254c0ceaa570a342ea0bcb9faae9fdd6f28223de895d05abdebf61fe9b12e7a2a3e478f36b99596469d69cbef8f4a6a72007b
G = 6fb4052ad7c89e3a5d5953b69cf31b3b1d1deff54edc48697c5032d5cc1b60a489721e49b356c8f6c8d4e783296406a2954012a012d731fc8e30460b39f523ecc12a9b79bb91ccd30ebe262c76d063f8734a21e6b5fc1ba1fa3c792026923fdd021b9c87167338ca8ac07ac3d520321bb22c8a5136c7928f3f1ca57df3bd482cfb5f56df32d9fc74056993b0cf99a71b1833f2b3fe45f1b1f257c5716be6cde14c1f489bf0089650bd733e7d91b58f58cb94fdae51aed18d24b277cd53ba85b999517395b9834483bc9e44aa6a5fbfb62acc0dc1ca07f53558134fd277f5ecb8d9152f42de47c22449e74c69880940713cb1c63bd1ac3301062104f95e47ed16
Q = d2818449c9c037869d50ec4bb96b1cf1be7417900c04b7c5ab941d1f2ae91a25
X1 = 7572519d599abaff0c8de051da1506ced944d7888a36c1307f4eec30a581ead1
H1 = 1b88e2cc3758db3f9d47a2f2847d98cefbe43939bbb2c77962d8fda19dab56d078ff77a1933fe67ac19605bf74522bfa488b0af7f37087f6c7c2efbff36669dca7e105e09415ffa6a5aedce274b22ff93034a270ffaee9ab6778f0c0740121f61d6498d65faec0c19ab7798bf00cc135cca80ef58250366433f94b799d47235faab4c8dcf35662e6d2c1e50ff0d36f71cf22be47fa568bb536ff1110bbb93e9d6536719c5d04d195e6038cc82783cdf4bdc67f2296ccf9718ba6df5bd2bfe2f5da933fb84cc0c32111dd58a0a4b596d87ccccf2fb27938a09f42ddf08973cbe7e372684a3f0c3b62eac3be784f9aa9a46bdf09992dd5280fac4a7388cdfff495
X2 = 0af9701e4b97a323414b3445347523b33119f026a530c9033a218487537f0ff7
H2 = 0710a85a26be128d2e66433464e90b25285c36dba5e3ab90c1c8e5ed973bea354f66614fcc6f8d3c15dddbeb515ef261959677b22a4c93c96e6481f312a1efce6562b928d88bba46eb101d6d41c0bff547e0f3c1f96544b67e3b8cd6c8cce28937909c4d1aa0f7aad7e237e2c5e26e83880c93322dc80c96d19c9a5c07fe4c88f711526ca52f4d06a0bc60660262d07d3dea789593ac5dba75c69576cc52a0303f40afb461fb8ff6e9ad00ba442abac76f74b6d6b8836083e66f2f127bf89a9959b51e749660e746ccc53d3ff6b4ffa11c4511d45baa771bee9a333d9c19c5551c026b0aed247c73d5eec5439fa47a203b13da9c46bb1781d8ba715427eb7e5b
SS = 7429b89b7ebf690cc9014fd4ed88a6bd959bcef7de6055376dff01ae0a3e8bf3ac9b23ea6782b992d7ef5fcc90483800c8e29736d52230b711461548462c9c1c4ea485b0002239a4b3602c1b24e9e79ed3539ee8acd24db5b059c5cb5e809deaa9aadfb868ab272d9468a7dc6de55002af27e8dddd5ee37873cd5ff54e23baf5eb233b5fae02165e2efcc3726a0c6f02c563878ad25563f843cc52900b7b1aaa930e47c54cb068cc65af50420234caeaed741a20e2238665fe6c908bf32eb12d5e795dc662169e5953b75a7a8e677fe54ad291d96dfffe65bdc695eb7c1f038718fea0a9e86beae0f9a5feb552de2b2c21b561ecaa216c2efa43bf484575aa97
P = aa650cddb837a0dfcd44a89010d2b7f857e06c75c7c4b0badc64342278e2ac5d39594d41bd74d82b370caa11cc804c2f9a1363f850d18f3ca5d98d0f06340ad5d9fb155367aa514261321985efa42527dd902ba25206aeafe01dc61538fdfa5e8d6b2eb40a625755d6b52f9c1f6fcb0f074f81bd367dfa35909368d4a47aa3f755eb6f6d2e2af4a861f40cfd6f2c4ba69b41a4c567b3f32a283e13658fec9ea867b39206eceea5db22e817a9beb69be7500c951c196d0a694b23b30514bdb1184ffff499e808b634c43737e76b5ceb3ec11d8d432061cc9f00afdecf9bc4334890d3145f7d42042e9d3d359c35f9109fd02c01fe0adc3d981115f89883a3e35b
G = 3b7dd74b515dfb018339b5f370ca504b44af401cabcf351317c7ba37bdf61e49b94330aa9c8e2f3675d05f4b8d926dd7f179ac6c09f4cb00f541719f905d090310e1373c8a6bc35230403b94f29f095cad03466ab7061260cd9e0abe6bf4beda9dd37990c2a6ae079133f68629b2a42cc6e81f3ccb630c32246283a9575d645f893dc318b1eb308fff6c56bbce58e4a3bded03047bfd52594854d6cd074d3516f1698c1b249ea557a08c6ff67841e5cf396187f4ca090b83565329f3a090fc2be4b75fcf86b585463ac069980c01fbe935c90a2001392471462407df69198996abf945a51dca747aff59a427db9110d49ba2840a4501b48aacf033b053775a71
Q = fe02f282e2a1bd89c9a571b5a5695a3d840215263058e114a2dcbc2af14fe889
X1 = 740945c82516735dfe631c481d7c179a450b9f5e1b2e2fccbdefab5f496182b9
H1 = 5b680e906a091df6866e58679e0d1274e5998d15f14c229a70cfef9c6373626e0ccd1da7d9a94bc443e547936c5730285c3ec570eb01db7cd15bfbc737712b2447a99601113bae78ab6ab9a0b7d3cebe94186f77af5cc713ed70f475e9da5357b858b5b5497b568ae43c8099093bf5f2073077ba272e258ff5cfefd83bde4b771da68f3baf016e838c4b313b45cb34d5e6fb607b9506974d35af7b6c325943afdb1808d9c641f5df3473eca697d05d13bb8c6ad959e34d0683fa2e74340553c083c90586d5a2c009acba9b21e937b268b9b25d01a0194b8ccb0e7fe64070d0298fd47618e88ffb61f0f0d472542b12814069a272ec8c24ffe9b8cba69cc93a47
X2 = f68c97495c0816e8211dc83c0988eb8d69e1d951b5bb613460a84db698a99d18
H2 = 4730d8e965a3fb46d6d88d467541df1bfe87e3ea845ca91e13212b1dcd8fc420fa3a90678b49a3033c43c6f9f398759b632a229910ad9d12bcb8041401739e83b0e246000d97abb09d8f68c9092ad93a57081ed7fe476f5eae74592d9c80fd2616f03ee618d94c047e8ad6bf30e446f968c34a6e147f49351e99c21a20c991499d764d86f26914dcbd3caf958c532e80218b3231ac55f5fe416d0a00bdfa29d9ef746babe440de70195fee2a355d4e0ac3b647bb6be2a9195aba6a2a217cdb1488776fa581b45f86ab773eda884561e126d237dbb2aa57a1b3fb59d8744a49f741ee26aed3fa10755363c65b5e9c0cb993979a726cd3944bbdffc6f909a063e6
SS = 9fac7768d2c69f9e4826420b44b86ee3688f8a90b598234797a70027ce96fbe6ccf360724f5c6006d6cd1f4d534c81a6bee75d33ca4d7ba70a066011b984084edc4c63f015ca3798700505d5dc510229b2ca0f32ef037579c4a2347018a0f6dc70f041b0a52e9f6d0e76f96271d497a84e85eab4dc114a37633d3551ab532d8e56c637870f6cd518d7a200f74302fea6b6d865cf8a773060828e1c12e803e119bba28f06b08c313b8163184352563e90c486939e8c52990bcb2bcebc42001be9b80bb15979fa5ccadcff783ad8d7790b7b640ee0d91b0080cf2f4a5452d87cccdea3a1e8efa77d66e5b14a0134f4e2d5f23385a3400b418bd7e0a271584feb9d
P = 8959aa72274ab93f3f739aa9284d32551b714d05f1f1079c6a71357b5033c8a0b930dd7657819ebee8dd1949f76325d5284c51f20f59b008e32f07590187efebc69619508c1023d2a1ea1112820594d6817cc72e2abbba8e51a8d834415e0e4d105927e90fee0b4d7ca231be6556a5c6703839d3bb7f6eb8a8adb31a22b8940554c862b1c325b87097876a09a50653e629567b8d17efa71ddaa75cb81d806516f6d448aee4ca6f749e71376a56a8de44f8cf34a5a7c1ea4a772b3fa8fc4c5b915c9a2268ec72260e77d07c088e3c68f7ba19aeb4a4dfd71f479b8f58aa9d220086f75431a9c6b528ec31c93434596c7a5207fa7732c2374c9aad1c8f074f68ab
G = 494be0f3e49a2565190f97a97c1500b1b0a3b9a93de22394b7f5516b98c9bfa921bd969e3c0cdcf9a099ca24f3d3da81dd2f15fa87f633b6949dd8c44af8dae4d1337e38dc3c823e9a1a4b233ce9973d331ca8a6bb23b6f6c34333c9c640f777d18575bbfc25530a689d1eebcfa4724ad81adebe0d275956bc08a98465ff9038f01fb3d19fe8cb4a4449bdb6844e7189210a6635d60a6c4c4af58728ffe85e0006c757f43b8c027c92abf72b0bb78397614d00ed5af75a35ac7e8011863c061368401aa2bfce53317fa78d19f6ab2c1e7a8c1d27e6a9d3cf9243e24da72860728a69beb26bfb96287b2ec0de7cec5613e8bfe47571ea4cb640f8155b329cde60
Q = db257087a391021c670878fb3d11cf592b69bf2563d6bdfc103e58b4ecb4fcbb
X1 = 39b56d999c5cd4e29deb71d4f867d225d8660ba957ea40379fd4546ea04ad6d5
H1 = 2ca8273e3ffce106d5daa8dcfb07812851557da5ec77f356bb966f43c3c893e874a8cbc3a711b8a33a6007aba4789c9fabaf9cd2cb4668d9a7b6fc02352a1f08f61ed4c7eae943303ff25862064835d0b76b6d524497fb5f8fdf98e7148db0a5e7c21aa329d42b8e45eb72737f8b6720d74090fdca8ff8cfb28d04400a6cc4056a7225a09d4a01fbfffed5f33676e23b916f43486a546e210898e9be1e0542bd3796dd5bd47023e4f02ecf85ad22bb0955c7157ed2f53ff01ea22a5099de99d620036622febc9e631bba88b025d2ca3ecb0b5239bfbbf7c104f8872d8a1971bc4dc4124fe36670749e57a00458d6b9ec9fbd6a517d5cd752310fd3ca9e31f01c
X2 = 50d418b9b8ed16c1557737561e70e1039cbc310c1f1b15adaba61fb79e114167
H2 = 6577c23e73bc271799471220ffdaf47b97ad4b5c526d34f1f3998f8bf599d0b3d3836f721d84df48dad7618656f63d07154e9a05e2f2346c13f13a86b4b825dc9d532570ed2865a41887be895861d41df50611585f7366edadc2fa48aaedf0034888965e2ff4546e233567d973c7922c028f052267fc9553ca2faffaccabc40c8d68cbd9cb7c50e4668caae262cddc408d93d3b5b5679e3f0e7d85f61ff531eaa9511c1e6c2de71ed054a1380d04a20e039eeaa7bc4c79322cc8927674926720b735359e3aa98d45e5ec39fba02aae0457f7f39449e6904a6ff77c3b4344bb4ef11707b75515ceadef2b420c6dd475114e181223428e19198188c801400146e2
SS = 00cda7e16f8dbac5826f70ecc762f01b740598a255993459952b5a5920036695a781422cef5c7cbff594d249fbe3f0eb93322b81d6e07c9fec48076a8a6f91d67464a7c6bea3baccff06c09ef5753decccacc46d5dbafde7396fbc18768192ca04b02a7c980a5ce225eaf362bc73a806fb52fc0255222310c9c5b745ad17f164c64690f487f71ebe2d17a509c965743a23b29bee4dcbc9496d9c904d185f3f42bd5961233f0a905075335bcda5b1b6aad2f6668d15e7ea7fd0e4c31c84c55994666819044aecba0811c4c12e7179a9dbc691f14a322676367b32d9f120988a6e4740f7e5682892d159b0a4c194770d45d6f3d95113c526e1ecaa81c748721240
P = f53bfdf933e9b748876a74d96d6d1c9b72e13b4db7318e23e4becf1f742dc04b6f7efb07bba133cd8b4a04bac9608d7ffd1bbffc6d1bfb64238471598ad2d35df5b8dc835eb6836f52601941faf0c0a20bd96e63ca5ef24d3a0bfdd4f02147bda26665689a42889c9d93c1446ce03d1386049cd29aa3ed50e9c7d3925123c1df45e21611468e40f90f258731eb8ea63711249d5d2009d2214e45f362622794791875f51b90fc5c5eaaa51f1b3f3364c0301f0efd6fcd9a6aab2b2152a6931c7d
G = 1a854044b1188a75ade217b1d175e7a40c66ba05b80432bf69a83d93419443919a22740a7ebc0faee6b8d509495a39a01ba811420c477577151ee45cc2b8760eab6ebd4f9de935aaa8be63ee441f4e181b856f47440d5d33b2ad7490212087aafd229226c7a8a44b59c87b363188b37907dd3fa5fc76e05ea1645844a14d928dfe19851158fc552c85c49fd4afd6dfd0c5d1111032eb7274798430cfda94d10e27fa3c4a24fe80e63fa6d47ebba1b16dfb40a9ca57d7aaa2cdac424d36ecae4d
Q = dddc4a0f6b29d9cf0c477ab6ff028b3b8752b014b2147157482174ad38cbac21
X1 = 6190069e675b3131213658842b98dc3d313d56f24302e3460311c165b400778a
H1 = 858277691306c1bfed84da2bf5b1b049dc6241f9eb032abc3668793e8678cb8d4c9ebd3c35b40737190bb08f3295d5d077478d85430b264d271d64d556eee0dd1dce90e98e25420ab21924f8586568d803ad87a626bd2223b6ae47716c414a48552d8106d7ebc358e02dd061395c98fa5f86da837c7c5ebbe3da538e6fa4a4efaa35bd5562796e34dc2bf0536e20b017518986fdc7141a1fd48ff22bcf9c549501dc3f3f67d4d23742240ef579d87a2c8b93e7f6ec99b2d2c3b7a3467f433f59
X2 = 08b4571abaec77a5f18990f5b356d6baa26a1920c2c8914d991cb25514660ee7
H2 = 2abbb6f0fd5572873aed24d50a269f98aaf426de6cca1f174e0536d306d10444a621e1107b17647f02db0089ea75d5525523513e568f28a547820555864c46fd476f9aed6c7be2d5b36c3e9c38f2a012c1292532e5c6a3375359c1dd6cb6ec097c9dfef4d81cdef5cbae8e714b65b64dc1f548c62d028f0a8020d961398e9d998c3caba032429360d04a7dbe8b594e682e40cd6f9cefed67b3dfe6853643d6a2e85ed2c688956c643bca7aef88f3e53061b631d194ef30dd69d91b50eaef2ae4
SS = 7cfd952b94a2e665d33648c9db7d20e2941d2d5d92f1054813278055dbe208880a6506d2b451d731edb5cc95020dbce67fdab795047edaf6c3bc5af792110cc4e97a9073ff932e318f57def7ce66c74a1f8a3049b86eab9939263531fcc0965260bed2aad66ca41d58c729fe01617c8281512cdeb7f52921825f21e9ddb586ec7a8ad101ad623bb7ee00586da8aeab6f438b5fff732dbec00ca97ff8a1fe3cc2dbeb90c601dce258a40685c3180174e2d15ea31716b86bdc7c9f925cad72d499
P = 937bc4076fafa7d149326643e92f10cd89105c1241543aecca0ccbe8b8784f7a6725308708417c8dc9eae3520a2b22e59bab6bf945b9c00d9e59f59a423e6a9ac563f46121d93a5f76514345b576384370ef5ffe4290236210b9d67b95c554875274ddb5654b7c2494edfbc65e03f2ad055efcba89b15b73c74bb985b34715efa799af2bc74aa897ff3af5aa872795d128ec7ee1beb2aa485d60f424bffe443509b49a2f3501b1c7d31aad0ccf612a2379e7c3b675ed0e30050b97b2cd14a253
G = 3e805b73efbb8c69aa5f3534069ddeb0b1e8a58f5ba972c9b57403ff9d76f1e17db24f26241403ec174f14856cb4ab6de29909beaf5a2867225b10b4613c4c03ce72a51638ac4d141e31725d22185157f5a69e733f5e6a4d293ff566a1d857ae5f94dd5703e51f0f54bbf827c5e8972a398eb79634a5427f08a4d27e3bd8e23a30b10bede649b9a6d3a84ec5e1a8a5076c69ef13a25edb601209ccccc42a31065cbe90556c7e65a8818b3c0c15e814cc3ffcb9799a136ba03a83b2883a5b9914
Q = e288fffc545e62548ee6475dff5297b1c2210ab9097036b1e601eeb97984675f
X1 = 0d3401d03a68c03363d67b6dbe1186f1699200a90c4652b5b7eb165b34173ed0
H1 = 859f2321b8ae517dfd075f0f3387fa6bf0ba38fabaa9d327c8bf9293524334acc90365ae3600b4fb41c4feaa8b750862176c2040916ac5fee361c3110b6682a27f1944be93d605ecb4e4220f467ea876298ddeb6a18a133096663d65b4c53b76309e936c59d0171a0b43f5fa184e840e6fbec9a7760a42fefdffefc4436374fe9ea778370782a1999dc997f30a439eda59c44eafb7940bbd4d9da5502ca20a568281415959128ab0bb53a5b67ba61f502580dde7633960a15c78d2a29041b036
X2 = 011f5f90f8c7b7b5a424fbbe0b2e3841b2a4a3fa40d26d2a85192a54dd2d9999
H2 = 3b84b275b7385e7b051ed7727bf6472ecf1287a536a13e16d97fa60327e9fa6f06d68573d51c825a4e22c27a4636fd916180b820877eaaa89c0222e68d66b67af69dca014d707cd43db983530d7d781083904cf238eeef9f31fcc1fa137716e5db704108daeda66ce17a1e7847ff991da004c78e49a0c3a8c3b627d7de380aeff3eff516ea06c05a32624549c9a03cc58854ef79af0f3af236d1830fc143bf2543465eb2c47c42c4c5c7bfd6a8ebbbd197fc282685b07e1591d78bdaef664b14
SS = 172c8bafc7afe6b60b57e9c1fadd6e220d311723fa52b075276ca237cd9a66ad058896c5ae8a9c71fb5951c220456d2e214d99fcfebbe640b867a77bef948ef0afeae9b25ac55ab679701bd1e100c403d8f5f7ec568d44e9eaa8367f18118d319a10dfccd009879f5c815ed283c06a244c9c13640c43bde97f147d4d399f19469fcb1e89e79070cf8aa3e11087d3c31d832ba67783a0572c2dabb2988412ca6d0d4d45d0cb61584351f225cee9ce33ced9bac96ae2e372d8871c541783a0c3d0
P = b4d6d611891e0a92b9a923aa84f16efce325bb69bdcac140f8105aff56f32eb022b8b31ce25cde03ce37b28a833b17c76d9fdb933c6fc1d7d374a1f913209712a089ab6884eadb6a2c22aa7b54fdb3377fc85279aa4a0b5f4f94c40ff5726fda0f3edea8fb44db3805ed76d44ad3f28b4cf1560270625ca05fd4db36dc84fe57
G = 30728f52f9911c38b2f926e25d9b12cdebf72480087aa1e720fa09b95b97af4f2e41b8f1adf202c378589c70a2462515e54bc92c81a4645eecba00b13de80b50f5fb8f5201e51363237f82dc83a995acc31b5c7b6be734bf9e8037759b8aa689ae3764dce86740e2a30c4497c7556c7d54e87586aaba317d15dc997e14aee265
Q = b42664d0585a6b4b75b17c5a226b16d121759fab
X1 = 27d766c1087badf59710379e58c61f5c4700167f
H1 = 5e9784489a5d3ba66585da31d46b3caa56ca9524c7684f36d8a8f8909410a42a0ab9b18498708b1048151345d7fd444da741ce96c7c00c8beaedee432a7091872fe26fa268c440f917b9fcc06fbc8bb2aa89142f8ee66aee4bddff4b8422021de12037b5cdf59e8b806238075b31b1364e13c74cb98e87056f0170a784b8243a
X2 = 33ab65959ca4d5290bb54eb95a13bcc8248d7bae
H2 = 8028c9873296f3536b6343ac4e1e53eac063f9cbd0f5cbb7c00d0fdee2c886a8133a7b56cdbd3cf1b83031ae8b5fe2bb6b82b89abd9914223a11292d8d8d66e9d485120958fb7ef655e8546d6f97be456fc47e2eebc25f7d85ed07d6d33ac9f82f31cced592b66d36366e76882c1e98da3f59dc19dc2afab5b18ee57409d4720
SS = b4aa5b7432efeae90dd440865307ddb6b31c503d41c1ae69a3607d00631416251e1c69b7529ffc0844a6b50248fb2eb9df5605fdb61905020427d2d5e1654dbcdf0787967c4c93a7e8074d0724a2cbdcd383f0c75e1d65f2bc4bfaa21f9580e1a9623735592af4dc3d684e9ce3cee6ad3525d7415517040ebfc10e1f285e20e3
P = b5b19c576cdc91b805ea8fef8e71caa1f29b1f34e0bbafd9b94c1012b952741831575a134fe0a17083170f2e4a66cf871fd036357b44e90ab0a95854936e4efda35d954144873de1df6c4891bfe17e68a01d6aa052f0de70ed7e4f780f76068dae5f91c09a88d41eed3fdc95537a6fdff2c80ca8af279645bdee018b278a306f
G = 207213157888b76d6b19815efa3fdca54d38344879c777e5e0e45495763ea79e2c4b98226fa6a0c7ef1cc0bb17be2d68627c274372b0e055ea5a4defd564d4fd976a060177fe4bc2333425f580cd51fc6e312357b75763fc2e7d2011239e39381a00bd54fb7ecc67a6f4c04d5118923b0852daeefbe2d22b3cde4a2c5a8fc317
Q = 92de530065495e3fe16f0af9b7c1b37cc1f1554f
X1 = 37ab5bd0c860e26bffb3ff1de7b3b145fb2ffbe3
H1 = 04ed1688bf426d05e78513ce0ac675ec2c75e9fa7fbc3cca2cb1362ae4624b2243d369453985c7780c3f4bba67191495b444c4eaa3b97f7d5af8482b3effa3cf0e1a6f09ed6f934ae0cdb7667715672819c4ef1c6c7f75a029e18d5ac91bd1ee49f341d7d63aa6308e1f9eca44ce1d09dace2cb247d10b4ee394258abde95335
X2 = 5d543eb54c8e111d5e1e83841714a2fc568c4ec2
H2 = 80cc244b8280e543b59faf043090445f348e0ed7314e1f6864f7cc8208c02dfc2c0300ade6e96281fee4e6cb6dfa93534009506195b2276f12174f2ba6b0de4b685e27262e28a62b7553ef5a0b538505a952c43f6907381474c8876aacba22a5c7af8f39eb2120756361d821e0831c2b5a70e98904f5a8e1649a396bc2477b8c
SS = 1b3f30809cb04f49019156924ef3d342147bc31c05d59b6d85e5e426125ed829ed380266faf9eede182be5134c149fe1aa3b4e1c12f2023b85c5e371601f70003e50d222557fe1f556a3252e45bb8c5a1a3498568539beffc9fc3da42a82091a2a26ca04a0c59948f0aefd4ed76fff7c990432fad534ba42aa6541d1d01cc424
P = 8801db065824ea48a0cf4973c6ba2bfde4945bb4642ceb28ba3833871e4422aec7b61f47c6933deb1fa8ed7bc67b6bf827cafd4469c55b57cb03c4fd7ba73aa2979867ab502ffa962cbdda239ad751317d7c81ba20e4b09a77727f0f5d12e228c1bfb663f7424ff8ae7b8170aae007a13fe9ddad6e5a1fb3c403f3bad04ff455
G = 2afb38db313918c12bd57b2428f2fe21e70092e06d7908d527d1fc7872179454a172e7fe4ddbb3821c726507e34f57429d9f39ae125bcabdb10658b17a14266af0cf245a77de63af354e8b4116a81981d8307f672b3f4a578e41d0e2c153df7769959c33e4341b52fc14bc1e4aa5d5e2a324bdd11f3fdfce6b5c30066059d2e7
Q = 8e4230c78edcd964fe2e109d07f2a281909fb4e7
X1 = 4479282bb1ab1cf5d714945ee81e95e7ad7ab86e
H1 = 44dd79e4e4303b6fcce7c966c15ee7f04171ffd8c6bc81ca5b2d9742f102a9f9953bb16f7ee2a554d02520773340455bf4ff09b9b49f0163a355818d09db1554b343886a9500b667be25ef6a44a89303eabab79fcc9925966e07382e333c149559a9501f916b4916c7c5e6d087cc8171ed2c3cb20f35dcb1a5a138d19bb2269f
X2 = 37cf47c8814269084dd16d12e8246f43157b25ba
H2 = 75b8de213ff548a5937ca69b9ce638fd9d1da6e77cda7d8a06a2a448fcb17e8a34a3a6a64509054c218760bb2e47896fb190b9606797310ae86c12eb1d1904caa8de9cc0b8bf176671e8e473f591252554021838ffc9409afe1c3b40ccc681aa0de9c49a3e4016a6fa403257a1784cdbc03bd68309f3c9d9e70b247622ec1356
SS = 800fb34c94523264aa3496a80773a61bed4e8ef9571df23344f55dba500e6d611360c1f73ab5ed68a42c822ee0a95464e19d955b1d952aac14bece49f8abcad1e8e48f1ef3f188bdd64f207ec1747ec675c6f58697666dc1a7a8f4c5962a110b09145bad6096dc7c7f2ff75c6ad06761b3a424dd13c3a5caa588d70266ad70c6
P = bd4c0b4819c69aad821e0465300560fe71b630cfe0f3e9aa32cf47d7c3b74b54cc1b77b1a4275b40136cf4055fb52fbcc70eea36ea320d9358200f5aa0fb39e231ed5ec9224d4e70d1a7f9f9e6440740dcabe5fb41d0af1c0d19a4bb70490f88ce219b3328706cadec56138ddfdfaf2ffd3bad9e094c4de249e4aee224b950bb
G = 12523f63938f1f945bd0ac75d0a0140d010538602196d8b0ebc45e302cfa23ba52027c8ab852954df6f9eeed5621c4c0fd166e18fed7c4bdde9b42241abb9dbac4d47915a359f2030b325636c0e3a2b1e508e111dc5c3fd6f31ea6e77b8f87e4e31cdd13ff9a6064c843ff4445696af1f112e71749f70777ec850e63fcddbd89
Q = e1274c210edc83b6a34d1a0fbacf4abe3262d82d
X1 = 503467e794a54b8f62eac137ca359e0c29d17752
H1 = 4619379fc8efd58dfc5c4778a6072c0fbb673f9a4f91b1ec93a25c3165bc8d75547a041a71615dbbb72f641be4f22dd681745077b8de8cadb0b49fd571eb76f23e2e1f697ebb41341a0f3a5056ad73232b0753382c2911e8c1390c4061bccc4fe208a4192661b5fec06e6dbadfd0ce5e093abd05579252411a63c706473df527
X2 = cea0486956a3282cd2f6ebfaf2a4002693933e88
H2 = 6f9b3d6640b50a3eadcef935bb87d42a59a12b6cafa4d05d6c70a9ca18169a02a2f6a35fb6d3d9316661f79246ae760d35d9f3a45233c86fd88156b55da126d5fd5504bfa0203ff808f9017d8a216837646ad1ac357875ffcc0d60ac9a2b0a89528843bc768c23a429f86b6437fbb52734f7228c85dcf46926f4176ca04583d3
SS = 090f2448a0b2f780cccbdd218f2cfa77f32332713d8fd23e477f6504bbd9edf02de05caf5260e8709156760bb95ebbbdaef3f863f0fe5bd9bb1b64b87f32aa441519f739ba3256e3093ff98411bafe16426e39d0ccf4e8a4890c5441d14f1b863eac4b3cd10b5ca1092939d0b6c904fe252ba852a0794d35ac745339f0951efc
P = a027bd9e18750023df90b874315b51f60c38beccf2a80c6cd717bd072ff57e0a0b752278739d324ca22972024298c4936da92d1df2aa541836e3c90b05c733146aa044c164bf7d4e651b1a8c8d2c1295a599125665c315711cd194bfc486e5da9cbec38ee4abdb310aefec6fa11288e73b6e6413fc4e24b35fb6939a58721a1f
G = 3d53549e566f60991e8fdea5d904ea38651d12d38c07dd020d372e0b631a351ddd4845ef778200cefcb77b156afdb9fde8e6702bf4f29849435b2a84d1f574463e2db75ccfcd94e9edbe9625373e3e75eb5e05d233c30dd037c129a8c528028ddf1ddf7910916410c185371b7465d60284d9f1d892756834a4a5dad85455cc52
Q = f28925867b769f2f42f5cf5fc4ff01c4d86daf85
X1 = 50ecda941f844508167728bc9dfc0c2d801e39a6
H1 = 543cf273fad9cf482adfbdc399125c35d693e63382487d7699f3d40e412292c244d45e69477e85a5742859b68df8a554793b24bfc724c3aed76c9542bdf4fad775eeda4b8e6a5b75c47d50b0088cbf57b2d01d662cc76c8efae382ecac1d298b4c33aa4b9d318eec3ad4a59f7dd0f925fd206debb586860f692df1e52444b42d
X2 = 353ca8f0ea7e7495ba20b4c21a698265d4a68743
H2 = 0eae63e0eb6bd16af7ea0cc4e99e10d61d639cb4f9e2911d98a876b3018bdaf32fd3474d3690f2b57068220169cee3371b33978fb89f376da369bf5b209b754c2f93e6132851ffac82a9b7e412415d1e61bdd7cec5617c3315490a5d5ba690abf7efa5c28765f2f2a18d5fe87fd09b71ddc1b085145fb71907eb4cabf9893e88
SS = 82c803453fdf46f310ee84a0c7e6bd442172728383753a9262c5d8a8ded4ad454470c02aa8e152168f4441bb0e6de0553ca1b3f7271fa0a83537cdc42ad652323915d1754e3dbfd7096f9dfbb2737ab9637dbca1252f1c02e8dcc84ea53743eec5bd287d1fea130052cfc5e957bfef5d7132184f6b6e31fb8ab39e53e9f10769
P = 83c7834fa40e1916663537fb57982183e422a7c599b67ceb8bf4741691c6481ac190a940a849189021a23d79dd806edee264e246079124a4d8ba41388836bae1736ebeeb01fa147a6dfa2bc802134ccddd84dd8b6e4da22c13167473503e3975
G = 355c24ac098e79df146cd966e6625fc86c99bd80d0f7b2b3cf8f72773cdef4431246c3275116ef1975c766da644e720708ac27195796ddac7d99089cf61beae24888b2a468b13ffde2182eebc6dbe7bbbc4969939636daf77a2ae8683d0d5b3d
Q = bd6e70834f25e1bbdf1f064174d8efe763f8d0db
X1 = 8c984cc47bda0b7cf580ef0193407c567ea2544f
H1 = 5e8918eb6968f1b300e8ef5db0498a2e843633d4229cea3bcf819f05aaea47996eb9819a1c57dda7c784894f632de9ba0f0a6223e3b1d11a587568d750f5428b13e1a082a4ad730b26bcd97f5b175f0a69b171621467787f1721a92ba3bb6bfd
X2 = 668bc4c55729f3b50cd3d96794792fb686d07287
H2 = 40be97dafcf09f8277068c61db695e8485da68bfba2fec78ce2572308ad1f4453f623908d341f040b23f19df73e2fdb07586166af039eaa6ed0716865cf183723d41755485a828e4d803dc51152d387279c4f8195971b6ecd3eb36f4ee8691a9
SS = 7af325a6584b17c1c642c96420aa193defcadf37003b00d3043a22a67c5cdecef48b3641725ccfdfd6e8c1571b9bff3bb7e37d07d32f9fa709a3b6b8484f53e7e11db6f9b1635003eccc477e5256c96bdcfc9d35a6016bd97ddfd093b0023b81
P = d45ceb5ea59e5a116442f74c9ba2d5719cfff8f72fdbe73e43de10d2dc8870af592be75d2d9196b2f327f09b821eb8d011b84968b19c68ad0442119c133fed33617a432c1525d5f1440b80662bae3fffc976f568fc82db59aa7b2e0af9bfa2cf
G = 20fb134841d41fab9e2d7f908ff0421bacd2a75944ffbdf95b51af4f405d3dfc1549e698565d975f09947283cab73e15123111bd368b3dd7924afbbf82c7e61cda9a5b19308dfc6250a57b2158a59d10f8456dfbe21764df75ddee9df6ed1e17
Q = c9baffcac02afcb801cbffed679093fc40aa90cb
X1 = 627bcb99399a5787de8bc28d137e4c5122671430
H1 = a415a74e770915aaf892d625896a560d92019c72304967f2a11602234c4d45ee4ccdd7da5a57d7f74f61cf1ba660c82a088a6f4acfed5f191e8a6c8664471d834295c9bc4726d1206872f356b700c4da065cdda2a719cfcb816acb5f4c0890e7
X2 = 4deec54684f9919b996fbe4d0441180f6f6641b5
H2 = 2032550a6f5c115157e658f3165909119b9a5a0039e37978043212a77c202605ee16024023ba50cfcfc4cb67d6f596c6526cd855bbb9b6ec6a11f25bfa25427d10970fe6da2677c26fd5d66754d3cb351f553a0c653077e125359477f3d90348
SS = c05b496b2a73b88163e3e1b574c8c6d075c8cd097aaa48cb975821c92ac4dd23671fe935cac4f69969a78634d81b704c03bb031690254642e0e91ff9e394223eabdee16b61fa66ea69198792de39ad7dd740581c60c4c85e6e971fddc4f1bd1d
P = ef3c27904731df4927a3a4984df1b7d1ec0a8b93a44a91c429f5a2d81e037fbc5a40841b655af5f093a22323e4696d92c8e6da280b128d875fe1dcb313f71fe5
G = 405a0ff506f12e41366685149909a633c6fbeb9ca16b6ace85630625fc8f34750d537cbd420c4011fdac919ad3368b0e702fad45e3bc0f7ccda77a34d5751690
Q = e950e09eea3b9a9ce09fa57dc7ba72856f312855
X1 = cd90c7b5bbf8d9e56abb51742daa7074d3858acb
H1 = aa2010a4aac94e9cb1a459866d0df5116a0969cb11f37d6369b7db152816cd361a9b5a4444fe582a5df3c23e30cc93ac62d3f623a7fd52e9637d706c2e190ba5
X2 = e8642d7e36b46ec81d226c9248877673ddb85d6d
H2 = 97a350451658feb0e26f10ce8ce7ba7bc26868e11bb2929e9e9e5b2a70d640632a85f0c8866847525f599c6fe1dc24875aeb223ea091ddd30dc2dacdbee9b83e
SS = 125823781a6ccfa7f182771c9a3bafba45c6f5ab5b16867555070d1b873638b71562d9eeb428e6dc12cbdd785bfe9f5e174f3bd7649bd78d3deb50c0985ff16f
P = e887c93bf88652c2d484511ba2d0989cbed17ade5030c2a78c10b6cbbb9bb9408b502583fd4c691a2f7a14dec8a2c7d139cadeae98941ed916fb54841ffed409
G = 317925d94a06346c7da19dcee2f13e6118fa1fc6ab1d582d0aec6847235ff3e1d5a256a15aa13a59e20b4ddda016ae2e39ae746e4bea50f3fb3868da63192479
Q = ca40c8856cd4379cd4cc4bd769c1a910f172fe19
X1 = 9d25e85ee74edf027050545d18b9024781c70b47
H1 = a2d4d00e7e6114bff06c5d8810803dd49c8af21874c3b1b869033e196c1eeeb4e8170007e4623722c8d5a5d9895ec1c7a6a09d729b0ef2ffd9f75bb6232bb582
X2 = bcee628307a7456d3c01a93e2adfda095899c686
H2 = 431796ab5dd0c801a10e39cf3edf90d8bb2878e8dbd21a648e5b479b0b31479c0aa6779f9857e11ae86f304df70ef4af485a5a3dd620df567c90e4ba07a1b672
SS = 37e4213d4136d35802527c3ef92d4961141ae4adbac201b0ef27b6fca5fccd9933aeb1730f5a3023369213827726b59636ada60197c05d12f08bad30e16959ce
P = 029d907dfcc70a8b02315472213d2b8e62620032464e532a253119702ea42c6a697a22868a4ab61887e549c63979c1c6216d29ffe6bda5418e843936467cec92ebc43911e0397661f473
G = 011dd3a9ac603c3905d1bb0cfa742fc2bac3789023002feea82c85f74bc272b710f535aca190112f82fe02b2c4c1f5f1e15bb6409f19ca88368a334354136d5673127f1efc2b045e20ef
Q = 0f73b59d77b05a821418411c288eef5aa5
X1 = 0d50271497255c886ab9ff58c9928be189
H1 = 015f85faba4012ed42cec371df0372b21f12cb28cd3351816ef5386bd50e485cce5d4d615ab4af68aa4a68ebd71d42ece51fa730a62ef26ae57d8ec121eedabd0782cb36a2072e549d0b
X2 = 0e804ae52d70a435870a3e67b679d3d85e
H2 = 018edbba7b495d567ac131e9cfa0711bf8c8a042f000f88a5cf636028306055e0754f96ef07758777fa19c4eabf6744004fcaf618d373b77d0fae848e9cfb409f0a971530299975015a9
SS = 00511083798a2886233543fb2844e0be8b273cf666a8a7995515e074124fe389ebc64a3dbe089366f15a7fbfbddf6586496c446baa7ad6fe046971d00b701288a6300fd97b24488257b3
P = 018484111bc669683242ff29ab40ce888505000748a7b28d0218f5458760cf26652388f5b0833cc756cc1a1fe531125088f2e681ccfc5291b58c5ade9bda76c80e3d8781b15ffb5bdd2c5d9856f1902e531955e18d58fea00b9819e90e0e3ab70c4fa0b8fdeb34b50f9737eb47dfbac3dd566a69ddadbfff1cc651a83e8a3c04066ad56327948349a0428e8db11a7ec6da21042fdae52c026e84ea65e25a21bbf931e6b5f0c9825b5d436cdc34d4c35b
G = 0040e90c2d24908bcf52b444cafffa568f89c79d71652a256ed9369b00e3b44625524c1f1ab891b275d155b00d164c90d5d4f85fc8aeda971118297e13719247a9dbceb4c2c33fd331fd44e2947f49bab6bdd699c174f11622c94441102c77693405e6d43fcd2ffbcc17cb0e9adc4a055ebcbc9c4a9a5e332eaa33edd3009fd0edb5d581f3f158723ef730cd626e6affaa42d47b64992590133a9065435df38c2d5a5d872b4df5edf50d5fc37d694e35
Q = 3b4a9f2e689999b9d348f0db28e12b1ddad6e53d
X1 = 28b96c45c0c934a65f500dfffad939f81cc76dea
H1 = 00a2797d8f07a07a3da69e0a86daacd88fc3e6582b9abb33720e398584e66b629769ca5f23358ac971d8eb6099a84f95ca9bd4ab32ec2635b8447a998a29ae4bd9a91d9c8b0d919063bbad38649220eaf865b83c9f128051a7c26961666f1f4e6fec6e78d26f6358e1ef2e5144b0297eb805d292418710d102e5246973c16c99f08361f728b2daf390b94c72e21ea21cdce984cf6043544ce06ee0e705e1ec5581485107eb52799c1e2f9149818534e6
X2 = 26815ddb7917456a7c54c2f7601df1237e8cd3ea
H2 = 00f50f9ecbed888595a7cd7848877ecde98030422bd35d061d917524c78700f72182fdf25cff09a42af2837f3bac2e7cd64cb6d5afa93333e67483bfd57adf701abd7008c5ff1249a5cb93687847437fbf3a0d242439448370f9642d9d4d3610da44338acc98882deab04e0d6b7be792f4651c5ebb270224c21b2a8c66266f543f9c0938e9f6d6a1d2fa48c8023edd2a5c8136f5170a8b85a8ffe65c8e2bfad20255301ebbfbfbcef0a1ae3d971e3ec6
SS = 014281b506703f2dd2019331dc2aa2c27f71211935093d548fa65414f2f13d30c5657303ee8502db94dcb0963188344febca0489e67702258ca664f0ae8dd3c104af8aaad41a73bb9c4c17403b7ad9bfca203e18e762b6e9d601ed7e7fe044cfd00322515e43c9c76a1e8608e16d768756701a8c3deb73b8cb3d1e47742fcf65bd6a097c52c7720aba1853c489272713fc56a16ce05e32b72cea989960555dce3799361c65bf326c4d7c4f1436031535
P = 1939ee8f5edb698d2f59c44b8c5d783d9e4bf649b2a916bfda12c4ba58f86166995cc7e7a9f50fe3c52de9042b394db3d5850751a1fdbb82c54aacbed9878b866cbbd28c0bdca68a48c0c4b7d74fa9e3b4e4f8086bbe31b9fbf9c67982f2bae3fbf311f9553424630578775777f4e12862c24ceced6643e4887f8a7dcca207240ec95354aa7fbf6ecaf35601f4c8dec5ff358ff2db1a1624b63134a908ab78d60f866f66a5ac08d86e36286ae96f45b517e308a1d4bddc5726aff6506db3e21f8b6545cb3907eeb8ab4648a369ebf80f2e60474b5e22da7480eef50b656e79b6ea7927dba6116083747732f4c2c7acf0bf
G = 11ea25f14707a669cfff495e11e42e59e76eba93371b61a0aa5eaae3d4e60482448d45cdfe9a6519bd59f3a4b34a41f50b694f0374415c17497aa058a2c71018d6d827179624a33a92b916730130b1f33137e588226fee2d59e9264a9eec1ffd5e4d3b56e276d825e9cf0645fdb88f8039e50788a2088be5bcdb49da6dc9c8cd42358afdf506c4770b59a94e2a4b05302ae82a6bb7927aeb970abe49a55158931dc09e590b92753a8cd15605009ce5379174d242982568a21097048abc64c63d00cc1fdee72665c99b041004279ab29884e2b4a6f4936d177f7cdb6658fbaa50e137ef5a82a2073724a54279467efb0f3b
Q = 0153b6a45381c39252636b0d614a2c1a883ca69db7940caa59312e0df51c441ed813586183c72bf47cf2e3c764a0c354bd8d94ff3bc10c7277097874ee2fcb
X1 = 01415dfafffab49831aae6688e91898b4905cc2f92190bd1431ba4f4b2eb47f203c955a3aea7e52b4ce8e75effd4fc61015f9436fdb6770edf8c69c0b487fd
H1 = 11bfb29e35bdfa1d114026b67e7224d1f117f67a689202d771172c3971a0e947ce00adb0006349866b561faaaa2f57a82287f2744db39216666c56e4f53e683e580fe1304010e9a6a4eabc79d5dbcd6d3e4731afd565570c5c4e96556a3972fa75cc55c12ca8ae098f92d2c1fc7d18f69d2d88a0f6d60dba637a884ef9ac23b552d923fb7f22cbdd4fe62024aa12b35923474da675dbf94cd3768b20b08d7446cdb2d04bb336b9b1f2a6a5e1347525e31b1254f6f92381ebcb48ae3eba16764d6e7364eed89f68976c8a370ab35e6901260c4ba0ec913881614313b0231c3e63b42846c1ed005cdabef0180526d79133d4
X2 = 011f875fd7e33bac934eb47704f06d73762b37847990893401f815bf27bf9ad2e1174bb39f8591ad83f7c51b85d800ce6135f4a4ca812835154f9f17c27060
H2 = 1433600b88d058c4af1e49a8173bb9c45f87578309e9aab2049234995a8772604aaf76f7937c7291da93a14552e3500e4ccd77ca40343400cf192795f7cb5ba947f9e4f7de88cd0d32dc08066647c20d003f10368a846cb623d06072934dd34bd0bb5901d6bdd4d42740dae3f4ecb0993bd041e6ebed382eb5772bba2a0f07b5a9414540cd9db7947aad2854f74108c01b6cf2adf9f1ec6fc844d621149aead1864e2ef8b436ac421921d4f425f51d3db770defaa0d842e132c602865e3362d4a4475be28ec45e9fe1644bfb25ac7d93e5aba60b5053987019fd8fc0649046ebceaf22f3a11ce73a5cbaf99b55520b1c2f
SS = 07a8a48eeb9326829dc65ac6c223598927bb66155063aa5a9f1db409d5731ce9197b80c7c640970d9e5073daa97eb2ea586b647acd9f1d7e4a5084468388096ba38eeacc87b3f3f40aaab708c4c2999e59a6a509fa930d33aca1b951bdd6916d2ac2dade40a832ed38ad5b4a874afb87ee7424f58ada0467c00ec1b1de75b0d1a067842e604a9474485501d9f157237ca7bc9df9b024510d6b6f39c17517979a6b9f98e7cab7ccbb41ea6b009ae9f4cda33d20f6f9198f5cb28e113cc10e8335e4c911602bae2328c8b47867a7f172aa7c726b7cd5874bdb7c4a17888c753cac22ad4014dde5d9f2a33f0b7728c09a342a
P = 014b5e3089b922cfcebf8cf154b61a125c39a83bcf22496c882b59999d880ac2f7b98f563f22a486354eddbbe94634e1e19136598c9bd60d0741ff5109f9fddb023ef1505a41b9abb5dfbf15541f71fabef4d2a9c581131a1d18f5fa85d1c3c306f2a98d8bf4ed18f0d3b6f9554e185496b6c8e10a0e33
G = 00e8a2308dc72be8b5a71bc5085a55d547685c6ef8e42f47695843f534bf0bfa085929f1a3254cf6377f3d72c063f1e085fa3c26471a5a9b9d2b1362fb70ed01eb2f12bf65c67eb67febfcf4424f63044807b1eeb64b18692e65545985e794e46e14994e14af0ccac9bb05ee381629aca7da2b264a219e
Q = 168466b9717808def159aa8aedd3dc024b92e5
X1 = 144350cbe800551009204fc6e4c1cfc042067d
H1 = 010e9ab4629039a8a5cdaaae953aef7e06a95ff21012541c89f5a367ccac085095c1bd933291960b398438ca1121bdc3c4540969918de7fad0081ac3b5a4f58479df50d579c56bc85de9a9d45f47e19b96d6da78a5b7351b9c97c6933f8771745f7f93d7f31e7bc51fbf62e08b943a1197700da318e71e
X2 = 1149e30627a75d66b28994e672b8689d27a4f2
H2 = 00b247bd07fa95a7e524ae4e8610a2a003eb0b6b1e640b6f5abcb29754fcdc6a597532fd9c15123084fdf67c8bcd90f048fded16cb2989198e66b38d922631cc0cf6cd4b259f83ec26be132b5748bebd43452fa7863f0de13b5a3c32d50716a5e233e330ab6184b3b5164d7676d7657eb572637b9df4dd
SS = 00e1da04ad93a4d8e09958799dce10d6baaef71ceb76e18da9a94ea010a03bfa26330ff662dda083d7c98357173228815aa52b7e10bf90e7cb026babce021f7bfc33dd2f08b60513fe1b983c8af6af8f9f1aa4323a8aea20dacd22c4901210ccf159234b7ffcb06e8300be00707bc01661156ff02b49cf
P = 0774fea562c960967046faa7ad966c0fe2cdbbedd157a9091f5093b3790d37c8320b9a205bd960f3651e08b26932959f0c054cd5fe68a368dd680556f5f7ecdbf02762108ff85d1e5328b34a8218ccbdd7d8247612d523e2d58ab9941050d839706fb8883f252058f1f0a938bfa1
G = 06014e3b8cd7c5d8bb7ae9ada56bef6bbe3c21126bf341a0de3582915bc13ca837c8eda609f80f84ef47e83031d757614e7efe7a814e517b48d4e921f5b9024a78653e9004639441ed3a456dd0953744a1042ba1ed4e3e789c0a0fa88823ab4b103fdd7cd0d4226085e217494efa
Q = 03f2d0c8bfd72eec4c2ef9e121564862dd35ce66cf43
X1 = 01bd2849fba70e892892d1df80ec451daa9d19ce2da9
H1 = 02395a411c35c6cca503532c0f7a351e63358d9ad2d7cebf7315a342806b3c7f58f87627f2e527f06ffae29dfc4c6d32f1dd7ae9060cce6afddf7b5998be9a399859aeb9c7822c1c93caa00fc468a531b41d3e15261c7b1ecbd71eaffc7afb8ccf9ec5fe166b20e452ad6fdf873c
X2 = 0304ea8739ec8e749b11733750f36618be918c746f96
H2 = 024bde47e21d0b6682fc875668aba6b455c570cc3ad31510585f79d8d2ea332b47135bcd3784c781aebb03a77e2ada72c696714de38eaeba83ad6dd9c72f698017f9b720dd26e48959df6660314471fc7fa48f3fa213f94d4e77c73f1c50161bea634888191b06b44369913f065c
SS = 02e6a98dc58a58a7ceb3aff67b0c1d2e24ea26285ea5b1888cec2a408431e36f36276e68428db5d9f40772088fea06749b70f06bff4449b3656cc870c13d153b5efa4b2ade6b667365d8a7fc769378568d2d7fedd9382904344bea1638d463655bae29455c9097d5bfd0b57e51e0
P = 0160d9e279278c9507b302b41cedacd49a160302eaf922951ad79a00365849e09ee08394491f31fe93bff91ee6d4d37d86a378c61a568cf7edc9a1d477fb6c9de4ec63c15deed6b237fbe91b0be88c80fe98b7c388b794436f60b8f9253afa2402c2b92571e13ee4dbbf4097691fefacf2864b33a50d79ca84a076a44962d889d08a12fe778996eac3cb97e969f365a1b44b3dde4089
G = 0083f7bc077f94a6e72bf2b8c33960c036c70f6b0a4bf4508d14ea1559ab0b46b2ec40fea867ea2450957a4567b1f2fdb1bcade80981a61f52e3ff12decf9be09a4f8ce00541a44fe50ef50a94803030aaf05a27c8f5e1b35810d7c9dcf89a4f988bd234201b65b30d08d558be61e4600812c39589e41793082f176d3d3d7615132935e7b63482eaa7c52c66ecf1b06ea94b395d905a
Q = 2e28b332e64f1162a8b321b1bd76c54a003fff
X1 = 02ed3fd5a682d4f1342850b96d4ab4f700e4db
H1 = 00ff47850f3c6d33f2ecb014742ee27a88052a0318131c5a924cd55ec839c0e815d839cde3bbaad233f11866eee7aa2b48b273babfb6528364a49ace54eb06ab71fcc0724162c9fa206054fd0f50a536ed08dea1b80707bcd1d2ce7d4b70ba92da3373dcf309b104468183a1e3cdd1a527c5ebb566eabe17b0e1ac32b5dc76d4ecc9d73061bd4a0555ba7164243e3c998057028f463d
X2 = 237540fb3bfdbc4bfda27f0fdc7f844ff1c08a
H2 = 00aaea8e484e22f35854e17bf2398f08ba68c2d73305e6ca76aaa5b8ab851459dfc23a705539449ae835e525fa304d0da9db65c958d2a1fdc19cbac66936ed9d1fdc76503b2b7dbba521723aa048dacaaca5487289b453ad3b672fe663e2e98adf4a452decb54bb8a786f0c4d7e12e1c0cf08d67ffec286e07136d335f82c10f4ddfa9cf668318fb2cff5fcf015e2dbf60c48f5fc296
SS = 013bef0ae944bc36e6930622ec8dca35439a08905e478b9415ad2ab43c14a2cd86fb2a05667922d71b28d09012b4028ac9ddb7735ed1463e86d61c12a33505950b211ff2e52362e2082ede4432b1d61c44447abe1762c5f1e562c9743efa2f93be7b0da6e1d1065fd8f8cdfe43631063c60b32a4b6ede71fdebca7f8d5d755e0de6cb29b8bbbd95f15ccc82884c968e5726980e9b7a0
P = 020b6c25867b63455ba84664f696b95de649586dbeb6d133d4d6a137c81f75d99442cb0525f430c009338691ff13bcbb84ca6fd3fd895d3d5e26de126d3942678ffc3644b0743e5c829691
G = 014a2c221eca15dd6a7663eb80aa2805a407618f3bc1a7fd703bdfb1b7c76f8e7b6e8bfc62cdf16f802b1a964f3c8d0b1a84f3426601d834cc63816595cc12f76f088745a0c8decaf59388
Q = 284d4c79dcd856d4309bec9220f89eb0f969951afd12f92fa2c47ed6b1a54048151fe4ba333305d9f785
X1 = 242f8bcf98277b1f1601ccd60a1807fe4250681dfb2141be47c88094fb89379b8d896e39f7b0bdb32f11
H1 = 009b633fc322c694555391105c3a99dfaa892e984ddddf462d28121806edf32cef6e69a02907fd01fdd92c43b87723883bb5dbafc8d28dda5ea0b07fcca951a1010e2d81ee85398f1b9e25
X2 = 1199605cba264d1cc0780c2b8fa68ce3af9e78d51ed12f83415c27e942d2369d0e58b6396277b187d04d
H2 = 008024343a917f2a59914e4c9d3ed00e4f54bc3d36885c16bd4ba6deebdd7e6cacf4c6e1f8c25f0dc77927dba28adb85debc37ec91246676878ff6d48f22743056a801ef93902eb6142434
SS = 01f98a70e5519e86c10850e03ccd1ec16db8be18cf2570690d9c9a9414506fdebb72656043f79e05b405e633fa2a53a0c6741d19c85bc0c9cd7a2610f4de7ea90cfe04568e2df1970a5427
P = 032069b4a9062fd3be2b9f64c2a396324268857dcedc5cb9cc245c86a4e287a8f37e0f0eeb0ad71ae6eff989874257217d7c8391536c56f83b239771afa4cae45f80ee375ea657f57ac48bed79ce5f324f81be2e6ba6e978c4d418d375d0d4d2bb21f4c7b283ce65d04e557091eb88986734662c1d
G = 01981a738d4f487a6b4a0f3f89dea970528de3271f829a47a9ad5441638437ed71d0ed8912f71604eadba0d1026bb089f03404ae62a2f947b39f2c2faeb4605ae322af5471e73ead794c71fa0f20f1b101d427867c6633002da8f35d4cf7c0f334340bff9d288b0079e3077ef4b49b93d53caec9d4
Q = 3e3bb4d05fb5865723efcc93328abb60fc3c35367035096628cf6f89c7cfd84507dfc752175b742ce0a6d0c2fa7c1f42da2b32eca8f43c107c75
X1 = 126c85e91651498276bcc71b0707183ffdfb2cd113528a3339f68bd50c521aaab96addc567aee6a5120df188d267df6d30fe08e7d619dbe71ec8
H1 = 01beefa31b8123be4d2899c8bbf8df7ba5e60ad6f88175e9fdba7e472973d82eef0d4bfad14d80327407a9b59a94d8fdff26b98c513e7f4d7ce2c2ed0ed749fac30fa23707972ca07de47636607422ca1a2d9d3f6567b014fbbf20dd27aa94c36b64304bf92e5518ca22ead7994cae75ced72c675d
X2 = 22f486837bfc22f55a00c294483bab87c5a172fc9e91a09aca62aabe0aee9f7cec4c6dadd5de9a0a87f5061cf140630c774793481d321718f3af
H2 = 02830293b37468d1d285cf6015742964f212d886751ea5cab184faf32104bbbd4615d24950be1d02db47f76c65f3d0adaf306de91031de7d08810abc12576e9d15dac5a90b207bd5af997a10e42a192ba6ca1b0eacf5b974142a773663272410864187ee2250130d36b8b7daaae6c347263421a2fc
SS = 0253a1f850815c6e967a7138660d5c410f4f30df60e2b2733e34f84abb4e7fac287bd171e1e50ffeff7a9af392616e4d6aaf03abab5f59f3e87de485907747198c7da99fef0c5e206567c36bb0e068b4ba484c6f335541c03893f96a8c51b74ebe78a884ad0973b3e852843e09669707b45abdc3e8
P = 0119adb76fe872ceb23704ecc161251fd9099f0ed088b8fe6887d9c1074de469b2e0f57a20cbea04d47fe2af9bb3e2343a40297a975ddcd2e70136ed1538d9c677f6d7b5c08c96c7
G = 0071ebd656c4b6bc20c2658974720c35df9daa2a6ee13951e44cb88207db17ac9842fcfc0851b674a5a83ad2576de82c8b092c5a60b462ea2fb68bd83d7131ad5228af8f2b9ee3ea
Q = 66869a1f86c64d12249d911e39c053924a7b
X1 = 31bbadf841d39c4f5cd4343e2de5f40a1e3e
H1 = 00f96ae227ef8b524679667da968768b2a8c26ad7ce1dad6a36e0a31da49ff26ea026e758e34980b6d92f486fbd2666592b7353a0124ba624303e2702fed8203ac497d724b4de595
X2 = 196a6cdf21e48075ded55c14d5729d3f6ed6
H2 = 00bd2391098db78fa6f21dd216c06b5e36e71f06b7b613030b6ebdb697a05630253e5c1cf684800199213ca7d23ad076ad42f0c63d88c64317c8a85459014044cc7a8da3967fc945
SS = 010bcf63805257c855aa4bb459d3eef80e92a5f33415198008ff4dc9906d8fe4cf13e5db1d0500db7ec7115d9adeef3a908b45f0b15de35d1affb239efa19331c8bb1a69378bd683
P = 06914a463f5bb00fa94373bc7a5765a20429ed74801fe2fa3c11dc5df3e7740990aa5e312e2f68c8988ca7908483c01dc006efbf7f273f0ba066cb94e8127bb26a4e67b52ed6ae06adc767b729eff3c29e4a26d968ca55dc11fa28f865
G = 05e169e8242f3dfa9d353197b7a96d36bf0f56a45fae2c0c56e19dd85bae0a4eada1aef8ea281e0772746c59d0d2eafa62537a5ff8e272fe22f16b1677b200b0a58e97aad030c41589e1505f6e402f22009a3de59bd77cad855ec297d0
Q = 01955efac94b7596b266f9568f118e5f40038aa2d5135fed967f10fbac6eae08ca305ea6534fdc0d5a29a243b55343
X1 = 0065060e11b2e71f9d8d2d8d427cd863d163614fe0a4eed63a867eb492f7a2d0834e0d37dae4395acbadf3875b6859
H1 = 061bb2345f72d457f34fc8ad67b002a041c0c35d26f2f9e0073c3bb62913199197af06ab426f5dbffbc7e27d2a92ee47620f778ce123d82dbd94fc5fb04629ea0046c616d3266c29b43c73fe5c684903de72aee0c45ecf91f48252b390
X2 = 0075f062e888125cc1683f251738181857c0b304c1aa9004d2f049a7d967ee01bfdfa0aadc82058ab1251b7351ccff
H2 = 0003588cb95f637088f703d6729be3bbc9dbdb7e20d124dab50052692fcdeb73557743f79c32b94f966d323d45323ee000707635dcd52419ceddce1ca8a975b7506a80e38053287aa10a85ac568e9faa8e91f60f450b6a05a569fe1cbd
SS = 067d7d61177f61ce7a693f9017dfb99c0269893b8fd8c315bd54b444e1f6bab52edb7e7ed97192ec9995a97b207883762b4e3f18affd28681b5de4ac75b2ec605983e12f785e4a5ec91852858817dba3c42c8201afd3b65a8968080b49
P = 090d0a68f5b052596f152d9f221148404fa2306f58ee81a62916a47727289a00113f74fed7a786e7229a71648945404836a5b7d9a1dfafe93e77a376916b211577c78c6c18d0bf6bf5
G = 064ec06c221cc69f1975b27e19e2487d4da42bdb251dd44ec5788af3593994b67621270945d85553c0d27708d55733a624e7b3e118340b9446cf6304b207870c2dd11743ee11d4e7f0
Q = 01d46dfe9ec85b1a101ee65f1f3ec743980511c975ec0a69
X1 = 00364da9d95c114ded2df735dc8363560277f2bac773e571
H1 = 00218ea1b5f05f3554ec19faea4d2d0f37dca9a12f92105dcefd4ca92c6887661e4c0fd6201ddd67b2c3db26f6e6d999632230307b5590e541fb8f8e282e88ae148240814cf562ffd1
X2 = 012e1994adceed8804b7a9cbccd7d37c795e9b52d286fe60
H2 = 08f6ede79688a1a697331c065d89cd1f90fb12c558cad96fb1421384a81744cc038c89f386bc09e428e3a8f35a1a025dc623bb48995e7140afb6d127b1387e20b739183597a9d39ebd
SS = 027cc4debe1f665fe68cb25e326c2c370363ad923eeb695b9bbf9884eaf94101f116994607bcc9c1b5e04620d9f56d65c4af3dd004429be4e35994e389a7b98aa41f67b7cade59392d
P = d1eadb20a508b248c566b16c3dd806bd0bacb6b3df42902c22034d310daa2e1094953453d4b102bc063babb73fa708f8a9b3caa0eb9e2b3100b7971f6db29deddd5bdda733e87d399941f5bfb4c807979383e35eedc7eb06ee8a91f80f879e577bf16571abd7d38b6300458322b21dcc9002f198e0c221ac7e2a090a1245608a00148f29345e301091816093e48a9a819afc630f8ad7c960c6ed0e14eb59696a128d5b51729ea7ea3fddcb380488a1216fc60fabad8c41b8c2d185c1cd758d188277bbe07cc8b46494f7fc9215099c3dbcb84fea31c18726349c05
G = 412a5113d87a114a7ca92702bb8abefb627bb397016fd234a670bccc44d35c949abcd7fa36800e2b4d67efcb5e384b72ec7cac65f0f93c290e507f488148f6990c6bfe84ccf112c5747608804ef8dbc2c5ee4abc6d6a1ffb04fb07bd4c300bda836e945f10e09fd593bb36c0835974a9fd10ffa20e65265b75ff63f715ff3f60e293fca64f6b63558b63e5a07cf3c9af82eff585eb60586b6f8ad4298d83bd6b91ca510d80cf205e87177501c328d1d57ec56ee8140a05bd15a85c35d58012573f5170bbead9a81a72e0b01b25bbb25764c22ec03797ce7146d938
Q = 8aea635503ee23f8bf1a725755028ded
X1 = 6f11f3aea4f35eb0d81deb289232ccfa
H1 = 5a9c4bca4b89808fa2c16100f2a2298c16c4ff3ca3a1762fea1dde553f299022f38d210d4393a5d2347de61312049236d3b471671578f8813e0f1ea32ae29404f5b6c88e7d63bf89df0090a037d6add4909074c081290bf26dbd0e97321dd35002bdc597af128f153c6f333ba0546ece73c74040846430036b4c6191b77f10aa4f28577f096c575dc292e81ba3734d9b3f19b0a9c66eee1f0886be2f7f8002d2102cdf4c4de33a430c78410cf972d92370435ec8dbd21b2a8adca475b12c3ced8a9d7c21613753b765d6d4a3add70546585308ae4735ee206b1391
X2 = 8306b6b3d15599d195e5a3ad3be01e66
H2 = 20d0024e1db886573a45f65a5cef69f999e136e45bdba752a1ed62796e499464ea29972a6527f1a9fb67cd04e1dce5b44f5167de120de8ae6189417131a45607cb168eca26d152c9ea9a2ed611e9b15d232f63bff881787a423036e683a25b75f4162d16376c8ada7486d2d5b884cfd8b9d67aa301e1573b189bced2ac5f706e36e15bc30f2ee487b5f51f8f08457e592b4483cef3dfd3048d1d171d80897fc9da8c991bde5ccfcef2602e8409366eca74d16374aab392c2c72143b3202437115b79fd60414554e11f2a02f13a429651a58777c52ca2142a8c80f7
SS = 0ad46baf4c6f8dfe33c89bb7b803f6de5271210fb2956a55bb5fcb34b2f3ff6153d00edd1dac24156a1dd71cedf71f561fba62b2514114ae3d57c2eaad643e9c48ff95406313935f3b02ddcc4e6cfabf3da56a4c22e15a23ffb0404960449633ba6091d06be807cef89fcb445b9d243a4d60028a42689671f0102d6cfa480f41389877472c0c94f033e6c49c14163845a76f2ab55d7c956396c056eb69cc29b39ab4dcdf2344f90abcb54b26fcf4e73fc48cf5a31483463359c0bbb3dde2f14f406ff843ec179f553d05af21d01f450c9a12368fd94e35090242db
P = 01d9311e16f746e55b10558649f7b5f6aaaa1526d9c674121fd3869ed2f03027bf538ac0f1d2df1e87d47438df89ec6060874299d4c0590660cfce97e2b3eda9eb82a7bb24aad3557c8742f3bdea36114d1380ac78391c8ddb9aeac88fd103d593dd659134d178f708a29b793f716bd6092928ef49
G = 00df8c1664df44777b4d8326fb6540f5dcc63d7f893570ef2b95c2e472c20bdcc9398a502aef1516ae466977793dbd784e3d88330cabbe9ed42b74c1b7ee4521c8f15d18320ba6589ed838dfd8f7ab3fe5289ab5ad0c96fb36a689fdd5442e677e44b23142902089256730344cbba995acbf0abe08
Q = 03271fc679335cf492956b1ee3ce16c6076065b559e03bf35cc402767d
X1 = 01afe7d7f6b6bd7d96c91a65d817843ed61a36d199604e2300afffbbea
H1 = 01abc70ddcffad78cd32e543124002977a1b48f80b995042ab4a67f9e09faa1d6c39d11aad6664f2636790d6340e7f63d677f4e5ab3a740a3347fcdd772ce2134bd95e3dc0051f231c443b67d78a5a9d1e9ad3950f07e32c9cc71ffff435e03577a4cf1c5f75c9770078d874950809ccc343602fc2
X2 = 023d0218e849cecaad1f5a100ede5eb33793b77ca1587db0a23fad0049
H2 = 0193a287d43341b8a921b9910eb0310328e4e607bbe6c429347e8d98011aabc0d23498da11544f9f8ce46388749042370d3464e5fd2e69e772bfeac779dbd50a3f51315b1d3512c105c179322e26e5794c04a1b96faf85aa63e8dd814315de4326971fa4d9812d60bbf233b8dfb7c1b2a6116cab67
SS = 00e9babe3227e341681be44aec862ce1f560b92a4e743a6cfc9bfd53e1542d34a38ac4f3eebcb39c1618263f9f28dd8f99d8c971ba4b155ec6fa9c21391f33b35c513731c117465219f04fdc85267dd81dd824d692c9b75d34a11214fb88852fe1f5112a047b5317f8808a7fe38f9561b10ad42545
P = 7292af0f8d76fcaf5faa3d4b7b0668f4e32275fb506beab7b97f3d4e6830bf63f9b0f26ce608f7d1819b8c1602220684e55f42c70441447d74d413f770c9628d20e59e2906a7a4123d442bbe41b27e76d7791935f3d53846761a6023bc62fb0d1c8566af77
G = 6972fae9bffc7608e808ee72e0073b5bda24725f78b071dd7668a91222f9f2111ead1afef6859378de727e89bf594db5197d28eb090bf7c463f88c85fc2275798ca6e7b64d09ecf73df02910a918b24a43b1d74c180ab44d58c07ea8485c0a529d70e3aae7
Q = 8b296df27cb451a265b4b241936d1d053d2ae9
X1 = 6b9c9c6f2d09f862607c6e72f94fdb717d8d3e
H1 = 0dc76d1114095ceedb63d80d236db5e108ff367ecc1dcc9911d3ab65154f86c942a861be48bb4d243dc3c66bf3d1e979fb81021ae7a131158691a853c1ea0a0bf1c6db2313d5dcc8ce8d5328197b4c37b4822e4c28cb0ba373cd266ec7ddb2f049c0fe3d61
X2 = 3e69ef864746889182a350a2f93d69fa459485
H2 = 2125d3a5698a58542fef7d611d00dd77dfae877fbee31527ac78dbb3a2640d4b8e6f4cbc328899586ddd04309f5995772249553f86239619a065772fe7b9bcf6fe0d08059b4b992c1986ed0b0f56e1dd47e84edf6e649a7d3013ffa7760763525cb472aec8
SS = 1313ef2b22cce196af9c7d65ccd3cb32ce2b4783d1ffaabc825ed4243207466099b54cb906dcc499ae778a54c638fdd2e1cf41b0d4acfe6d9ec426f80bd8653884c2644881cb6a9065b8558a3ddb2852d1be82365afd54b5b01a09e555abfe5d29add3dd3e
P = 0dade59d3e0c5904ad799c884585bbe5117fad33973b177facb2ad19d6129b0fc326e5c022d72a4a230af4aa899580e39c3375c0ff28e6618a5a9652c09adfa8bc65d837eab6284f9e51cd1c67b4f6c9dd99295173a9f9666c139e623a0ce469
G = 0ba8fe47d7d23b3df7fc4cc88bd92491b8c0ad195098e3e88e2fc83bc5ec8f1952fb421a78d221b9c5f6052185c7c0c205e044053934c14de499bbcbbb9276df6bb6ebdd4bd85553b9ff31774d2c2a7764aff263e5411766847f15a6ce0c4d15
Q = 1d3a6e49897dc042fbd2ae1836404d10246eb71c0c00c9b9c202efafcfb3e52c41502cfa5716c56eda1b
X1 = 13e79d177828133c2cfcdceee85339e6cb32084e250a87dc73f64aa6bf411dc56939ef2e057fa1b7eb27
H1 = 018b5518e674b2122fdc58002574f809495e122a4544edd49cd93f66171a87a166ff2c9497fc40f2e27c175d6eb97cb8bc5206c73dd9b0d12c94338cf272c0847d54aac47b8263df02841175da1d44b76af0b8767397feb7ad49a17ef6dacd73
X2 = 0692d5555a174a1b1f72ed8a372a592fa085918c1105b5cccf2b8919afdea82685cb540d701152fad8ac
H2 = 0a188cd8b943362322297a04aa57baf6b2289c4c017a66f67cc4739a5e54baefd094888bb689b660f4b027564bda2cea4c1c17e85a248ae862e928d845b8cb5e9b83c3a99e6085dbdaee0cea97a17e6a62d958ed16531e63ed4907dfd49be6a2
SS = 0c7d58770eb3e74e1e20dfc30c9d502de27520899e9cb84eac4b326e854fda66e922b9e2704690ba3ce11887e1819501381219dc25dad362581599718b6d4d71dad7b3246ff9e6429047e27bfeb607ee0a5f9e97e1dbb1c06424730250a6c9c1
P = 0dfc58088ff80192fc99ab969fa669e9c36381f29eb23df3f75316bff0bc55d015fc96ff9314186b7f7acfd0868f6399567951268c4b6b117e2d86fb3ad1aea21c69c3f069a21652c31e83fc4a31d12d9f4d8ad41e5548770ad641b17da09b
G = 0976f61d2b01aa238fbd14dab3819b82122416b18fa49ea83e3b03ff288f416e0defe7927c8e3434acb927eee28414acdf9c2a27bb2ea6b4908fcf6f6a1d93c4c2210ae3d82241360465e6f8165ef5943a1998607b5db019fba130676e3b30
Q = 010aea7f9e89df6e7cc019618fe19a0b6797b05d53abfc58b02fc76c1c3656b01d4ac8a58c9901
X1 = 00966387866d055860866c226d24fb4fd5eb2551a378c16986291ff12544f94b28b375c4e99cee
H1 = 04c01d0b627bb70df0833c01f53c2a544262b5e36142b3e843adbbddfd09c8b274c10c2dbe168c2f69d82d86f5f563bc101e84404d941d8bb08055406601f5c853bc8f91aff565a9a276c6a580fd89c995c6473b52885a091d1bf22f685f23
X2 = 0069ea2434219c53b3124d517cee12c5af7e9168d410cb47a043e59dc57978b5e150bd37123f1e
H2 = 090599ac385d5d234a975eab901855de3f2499144924e9f2bdc653b2056143c124275dc38f0f91e358101303f678dda68e4946a2d76734b6ddde3b232b8d2fc972d53646382a0ccd3b3983d696c2af5d7c2b64c112aa8bf912e1a69a101b6f
SS = 0601f2407f2501071aa660c420675999b1a3ad772a5249757bb9e388ae9b1d8d9aa8a254bcb6c35eb80f0e5442a80c9d71e4ecf6a311bddd117d8a1953ac6adc99c5f047a40340026be91467a1a73f13d90bd1e027971763f2b25dcdb51f19
P = 166646862cdfe4fd4667676c77b8ebfd8ab3292115672e4bdd682f6497b48add1fe886106d4b98a3d261596ae3b1c99f88fb3572c2420ec50eb2bab1dcb656a82a24ea128b235ace404e8beef7215c589b90b007dd1fc45443b6ff36ade54a995e943c072bb6618a7d
G = 08d3f1ad5da6eccaecac2e09d2611b96a7fccd03063ec703413f823fa989cfb174777178a891d4809b4c34bef52831ccbf2f5a7d996959e7c9bbbe66698f859deba000ad44506bd8af83434cca4bcbdfb78c1a0075952f8b203b4bddc60e23bab55c11b96a14da03ea
Q = 15f0002253eb588362f1a588889a635799591d
X1 = 154f154a031d4282f004dacdae3beb781b7057
H1 = 082e53ec3c102a8f81f2b0ae7bc45c33a9e8c05cc883978c4eaaa941cff003540ca7bd4d38ead656aa6a4a90bcfb42fcd60188f47e4272940f8b7e58878a6507c46305fb2ba281ed45efa0f6c44f63eb5c49ab3e9f64a8aa877b739ffce3fdce0591eee56fb069f438
X2 = 0d1de16438f29caeb37661757413bc840d3d92
H2 = 0a2f3b71e3f6a2bbc2ad21f5eb1cf7eb84a5f162137d963c261bd4e445925874e9c82ac9027ca6c075dce765ddf5ab4b2afa9bb3193996fe3488fd792c70215e1a00519228aaa8654e2a313f0b94b2000441898c77342b60d4246c468892cbdf3d116fd94489ae8e49
SS = 08c20b6656f42e61101ecdd93fe281daf960b5b5fe6f53d302bb817e5b43c855b27ac9dc65393911dfb0ea9fe3580c22623b6a53ff43331427430641b449a0fbaccfe3c9c6ca16a6cabfacd9a79e0fcc6bc81a834b8afbe00955ba65bd978371f6757232eb7cfdc3dd
P = 983cf1729dc50b5c43733436f87d5ffe4b1f7bc664f06e2da41be6bb34e6ff1d4d2df835bade03e77d1b345f01e20d0617c709eb6d74c7a554280a0e66ab1ecf988d8d4b3f05785773776b1bb64d73e9d8935f9290b00e9c6c919df2f0a1
G = 875b67b60e8b9d2ab8d942bd76dca422e1659445a491888f5a81133920f50a52bfa7e9a2a4709bb2f8d6bef2ab3c4ea314038ce83b2115dcb43b3e856a0af0cf874206bd08fabd945fbfdb17630f7a5080d6e02c505f32bf6ddef2aea458
Q = 75a4cf373dabde5c1b7e402dcb3a959c499756d4feaa25edba16ac8a94e0612fcf42585d76b3
X1 = 7186aefab84ebc6b3eccfdc9f70a9325df5ded007f09a93840a0a47e8710aaa3ec0b2c9c2d87
H1 = 5ea7ffa11fb3421e23162b6e482625dded9b48f561a2a468af370e5439ccf6fb3de768d3c872926b4433bd7925b1c3813740975f1ca947252452af025c6843e0641541a38d0e36862735bdf68ec3a0b7449b2bebe1542cc94d0673d2f919
X2 = 57e65fd0ac8000d9da2a65af08ff626bae4ef2837a387eb8b6bb1c7df333acf856fa578fcea0
H2 = 307e68c048e83d36147212642d8ba12678221b184c8592e1f97805d8d54a3220dc430b8a8b91cd1214c9b42d7098eb7972bf9c1133cc22c4d419c7489c8aabe3af510680eb974c59518b8da3e82759ce3ce67c4bb0e1a7fa0ba946b9df96
SS = 847840ec958bf7b3816c30c2292c3594e14148beff5da5de73986af26913bf54b2e5c60f6d0d9a239afd9fdbbbc705eed80dfb4ff0035b7fe4537ba7df69ca0d4b120c01227f76a710636cbc8a899f6d78d518e081af9d37ade89987aa8f
P = 0975df9ee22a5ced2537cc49a14b0fa4ea8ad37bd94474a05f3975ea8947fe3135e18e96e4864d2948dcd8699f4a1a7c17d52cc797122434a92a4b7924625a738dcbbac54255d073b786c84d3ae0b15e8488b29ade85545e92db1d5652cb378b7ded06978192fd21a85a8d67a504d891f2dee73059010d70bf234c5495a0ffddde9fb2df1c9866ba9c3108ff7ee6802895dacd65cd436eaab88cc32609c8463d8a493b5c2b5555e1759625a5cfc9930d44767634f95b7dc8213137150d16da760277cd385e46cee5113741550d929a80863c6139b491f6051edcfa63758c4cb785456410a851ad64e91ccca06a98ec2ad080d68da2929aa9b19969a9aabb6d5ffc9795497bc9a3f69649511c33d75d0e3b6109c357d34387fb9388d62ffa12961b0fe7eefe312f4f1ba309571f8bdb577e6aa477f30f
G = 0931e780c5471cb7f07727730b5c56f4086b555d673614a53b8e8451ef6ba3186fa5483a76855d709b9bdb0fbb77ba62ae77b793111cbdc8f70cf35c6a9bef1146327d442f08895ccee8b689a2747a2b75eb77e82bc69715e2c3edec778e85e8423a351283dae2706fee59f0a13c62e8a4262f88059aface3aedb0df94985c65302d19a19784d310f3edfeb2735715911ff514f26826593f6aa817dd72ac115b61d4a35634b30daf373f4a1cfb3307e5281db90f277e9d8d7ac8621993693c70c3b4157ddc5f55d8b50a2043bf53d3ce93c4a2e7aa97c8bae50b7720d7b41ec0cf69f6f7b8031a9033e65a72aef750f28a0804fa97b2bb536dfad60fbeb51ffb93da0019aab11a8f23175be2f878f32b283be40caef35b139ed9968de0ee5f901ded4e93970cf5faf1a60b023b48ade882b8a8c608c8
Q = 05d9e7d5a587a59ce861a1e10661d3d58859edae27fa460df36b
X1 = 05120fbfb79c11ca241a73c4966d242d05d08242d91aed7ff616
H1 = 05f15760d4a989e9378909d51037dba08acada010cabfd446854bca767851fb281e6094dac7be7db9462e1e10495c1d0a7224eaaea39512c29d8a5051e2ae594fc5c1919ee888abffd45db8c1e8b0afe280542f27dfc7a2188a29de561d204541de4e5b0cc5d98448fb43cb580eb5eb37ab5ee59013c8ebf34f6aba51f5557dc491c47b4a9ea1e32e66c59c38e7844e29dabcc219f5b55a5217734833d81ff6e258a5210a421cdd74fa5bd89af1d1ed90fbac325cfaac665acb10dc8a0d8af20fe20ca3c754d1c05d0914392f86749891c93bc0da3bc8802382bb619792165d039519432cb4c717253da84b2353d605af15876b0c1c2b59fe1e7ef88c31c5024d4a0a1ef3ac35ff5529b7dc42fc43721fa6a12de2e19e3f123447622e8efe8b218ee86a05ed47344ff4b043b14b303c12d10ac56e5f5
X2 = 04f54d20deed02cc40743d2ce378776ba6c70f034f66918902dd
H2 = 016cdb75ce64e45a9d52c9d7a2a582c4ee917b6d2b9657e360ebfbe454d11fc946a71fff2277904961dda96ff0084ec7cee69a1532885a3e43854e501828eab3172bbeb03d3166b1431f4a740ed5cd270a093bf632f2885cb8bed81446aa5b6874eb109c35556e19e0e96023a2195530e83c87523aa4d0d6890932d5067191b85a62c2ca37b9ddbc18a75c4c502a50e2cf3f1d4d5db081dd660c8e9befdd23ffa7102abc0da615b8d9816a41e4c93fb89558d33fdacaa150cc47d1ca322d337281cd134b3ad46cf4ca4fd6ab11959eb8915f450177c633d634fe61824c586099e26935ccf0e19806c6c82178cddd71efc4707973c446198eb70ef95950dc0ff02723c5dc3d8357725605c69af351feeffdcf96a96d78436a567a1854950f96e39cf0c377cd782ef0cf30f29fe0f36d2a26d6909ba00a
SS = 05e6c94b0458ab60ab881d4480d5b23e0399476826f3d18581941184a6fff7e0ca995a9f8c08d073ba99573a4bd5caccb18fa642809b0e70d4f50f84f0f0b6c594008267d9118ab612f06c8e67ae8eb91c8e21b2166521a84a299f1584d5f8fb97d9c524e2e62fc7b751ef84e4439cea3896733e675afdbf226c87283cd1238d0aa8706e02fd1c83ac7be194b06dff7d1f19521b2f1eac06b5ddab9b6e1954d6d8c943959895872395aa2eb15084ab092b81a5fba192f374a55e295037f3c4b19f7c2aa9ca8f444807fedb7b52b715a3ea9344cffa5871139b75a07577bd85aeb7bbdfca9c12e24baaf8256e5059e88e7b4cb8a4f5eadeb5a052db0d111408f64c07b3de14049e1eca614d840bba00614b77878c24882c9aa6c1cca140f1c9c73d4088d03bf1b8d5de9c5b30f3d72389bcd65d4bfdeb
P = 24f8f0c75495a41499a6aa8fff7a214b6bd7a3a0d91dd6ac4228c198cef5ed1312deed376b1d850922f27e7316bf0feb434608b5917baa36b75503639d0301aa685e0274fb624a808bc06e435af566643d
G = 022a5e8adea697e05666eaabb16f1de767842a8da432c583399b3ce8dfb8411317fba9709d8f2549150587e712318898780cea799652f981d4a00237c70b4da562008521fffae4ed2e51d0d8f781a4e4e3
Q = e4f7580dd05f799ae04b2f1f33901addc129
X1 = 0c74756d7a0bd6e464222b85fd086685c739
H1 = 14ae96aa8fed8f6a79445bbb4c80325ce3c653729bdd676c0e03ccd09088858ffce30033dc1a04967d24f67f9e8b3f9149fab478b490b81b8934084221581d552ed8d9974be162cced2d5b150ad054b7e9
X2 = 5c88655520b1d5e7b97dca6b4e99e8af9a92
H2 = 169d456941f8fa6f0a5f2c867cdf95b1a6dfb8cacce7c943740c43d438b88e7250043ac3dfb6f29694fd35e3ae26b46c928ac289a8a00a18bc7bd17897975edb1b0645f213a35d094f1c5c4b5610076b0d
SS = 21d932af720c27718ab384840832a986fe457456e2081673b55f74e18f2a5e1cd83c4ef3f822b5a4ee4eed5efcfbb16a1cdc91ad37d61e648e13651d24e9998ba27a02b7150ca7f7dc234a0c2064977ce4
P = 28379735e80b87a81308d432314eceb7158d22b4fdc6b96f97b925bb7cd2cd9feec43745eb47714a55dd59264841c85654137a96cb4d3f1abf3472e870b03e83925ba2a4741eace6550e3851b43d1c640129edcd766157d6e56c55ae29d1cffcadc0138a3d46966292f4894476028eb06edff36de326d3fb84d742cc72a8d82b
G = 17232490a034f876a02672a2cb1c3b3c38fbbf64c295b6ffdc7b803cad4f73413856b74b64cfb14a93760e1062619dbe3275dd651d1d4ccea9195da1cfd647adfe67da6cced9df64a78630541ca68293bdb3e9166716ae01188377b2a4e13100ac1f3f1eafd1f252f95b25d3ab36f21a2f395275a3f923dab85d0e1454f5a773
Q = e56196e2c0c2ff527dca8a9d9abd28511f9447
X1 = 25213da45e081c125199beb9581e9ee1332831
H1 = 14c60c4c565b4d2fca4e081a59f2181a02f9879dac9e110e0a92c65bcdb1d923682480c936cec754e1e49ee201180e30d5897ec3251c47e4b3510be4c8672eacefb64968a95bfde16b1d12c34fb88f120573739ed60a2613f7dd32ac7f1e4bd63b32c243641f633389fa4f4d649861cf555880ef135e42b3b77fb8b7b43fb3f1
X2 = 1834af8fa800d2d108933cc63c7403de015b9b
H2 = 1aec7be2ebb6bbed7bc75a24f5695c1c5f2664efa39003dcbe3ad8503b1e6260253f7901f1488a875e11b6910fbed2dcec4dc50f13df480b34823d7aa01d4ecf0e6530917432c5d6154ae322de6c49499399996b02c168620f1ee2af128533a2740ee9de80fa0140022cfb9f84144dedbc3998f5d15d2fa1c48c69ed18560d06
SS = 0c143641148fcb99486337083e6ad4b842923019555f871ae71d13c762ca9ace68fc5a10b5d6ae6e1251e6b2e2ae09ba508eb32bdd225d08213b37f642a4b29f95d0b52d50ec7a3fb549b2635d71111787b71784bc84fbd38c44f10813001a7fa005317488c0e47f32c8e11e7842afa4b2b7a5dbb6b33d3c10098771db78f757
P = 09bb7089b2f8e4cc485e5fe032a0b3bf473c5509dcd862d28e9965f4bd854e2b85f43ab9b63c60612ec6631cde20817b8b1a7a21b0597dbce26d304b25fd7ff7fbc297536385dbcce9a69f1c09973234373e9f930e17f52e34691b
G = 075a57aeb68593bc14072722e52c4c925732edfa06ad533d83257471a2388f75f03459c4f895b1101d3f4bdeca17b9c03344d6a8ee241ec64e7a5252c85977277fd7d3e108e101b44019f298b17c5337221304d58acb99bde6d794
Q = 01fd1aa41677fd6f61c3adf31f908bf5bf8776f4f67f459a5c4e97a933d528c82f8e8c2dccb1b8271fbe15
X1 = 014d7ff4204295d79518e8999fa860ca7154f9b0de25db6532fe6b2f089d49b140d981350865a1df76cc9e
H1 = 060da5835ac81fa1c53344d03faa9802f2e600136c779f64b8424d5c9b873eb94dd189b04530788005847933e79285899f27a8a7a06b056050e355adaf66ef58dc891fea4a51d885d66cc3168abbcdf7dd828ae5f13c9e4f71d895
X2 = 00f37c6532433e50528accd542de73b73ef3701fa98febd61533fd0c1f7de48f78e0fa1925aa0e7959f72b
H2 = 0795d2303500ad04f467c13751311a15e48b01e594e74d963f114f9885c0fff6159679cfbdc91b6ed7697ffaa16f1532e315ef4c2cf95767d0d750c06c228ff6be4bdc8d7ac2098a3c83ec880947bbc955f9b8cee47e1d3ee40dc1
SS = 045825b768b56f02ee174a6608362f8c649ff8c20d828215fa7ff9fab5b314e2ddbda8896fbbc65312fd2db6910ce482ecd8f88fc9264bd0a6ce380ab094e104a11883042431c487015089073c1883f51ad511456a60da16c6caaa
P = 0a5e274373ebea332ba646ab83fbcc872434737a41aab1b45efd80acfd49432075b9e13aa92728ddb47b7dfbec8ca5c0f23b3276777c34cdef6709a92368883e5020efa2fce807c9cbfb0b6de4dd2d109230a4d21681809df08bac78f847cc136320079061193d06d4ca9aed13587fa1d7539027b097802f
G = 05cf08ed9d5978669913907fa8d425ee9313e4bc5935821149d96a2746fa5a6b7f8ffa4601d768f1f09e160575f1fcdc823c69c7dc2e43d392c9760b8ebccbb7f97e5412a0b4acf0ec30f3da97dbb1e15d20ec6796a74df4c5acd5a34c15d22f35af8b57fcdbf0898a8ba6dc9a3f694bf85967f95c1e3762
Q = 0425b36c6b4b9d1e059208592c6d00779f16458f71e8f349c5
X1 = 01819c2a5fc21b36838502b73ca8f0cc495d99b2fbff116d60
H1 = 03da489cbe0940b830e38ff19049f2aa3aaa7d98077c9eca0616694411c949968ad5e96c610e9499056d9c4760225169fdfab70d5415f9541ff637018d22e95f8ed0a38a866036dc00f0b4c4fd625a2db168a5a333da8f6895e2f2ec262cac8d07895fe039dbbe3c61ccbbc5d7e33fb093df2aaefd6e2aaf
X2 = 030cf338171957c486cfb324d820f701eb24840ab55788eba7
H2 = 046811d1308e454c6140c796b1b343dc2c560a8ec21d4e62eea0c1ee8b670091e31fe586f098b5e41f4f4370e4b75b43e4babddaf3f5f80fdc2419e8c0126658628c6cbb8df604149611b3a566209edd015f04e1e90d39987f7e754fa78914bf9ee641edf1cd4a673a7f1a322951a98c68e7e5a97119c020
SS = 07e6655970245f3a11e35c2d07e3e35630d32a71cd87033e0b0cbfb5bf8d92272e2ff5435da41b934040d3eeaf51926ebf99a153444b04db84622985be87b3d0faf898fad0c6b6995315cfd41d1c1713304cdb30e85c0e65e548f193a7f358388a8b9f2d6112be366ab02041e06b9a9dcf1f796dda148f76
P = 01ac5fd129dc4207f26d3890d60d584a9ee7ec23cb1603608bc8f873df69d53aea99552a788878b87f95567a4a34240c9dc087c65d9b13f58e73a500c49fb0b245129043c88fb96b5ad02e3400a9d01231da289118a1ab5e81888fbbe1365c8f6afcf140a34a7c51bb56c35d8827e4ac10a102e57c0e21
G = 015f54da6118b7b2512feb3ca518f54748da6c4ac1fcb484d9b10bdfcf804a94e47f7263e4564cd50b833df67dc72aba04341a2be342884b331f16899baae6b53c554334e6a3543f32f71d9ec5f85cd9edc3da9e98c81eb576b99bc4e003c6d940b30368d578b200d7c041dd54a42f0b7b5e6bc72d927d
Q = 1ecfaefac9e47e5fde0943937c275364f5
X1 = 1b62f5a9356dc9d8e3dfedce2736b11f35
H1 = 0046bb9e2b9cd0ba9ac8178c7e33cf0de62e3da3b6c60afaa2b5739c6f75370885c76ad324b16574cb784b85c4a93f1f4c5b2b5e32b76ed86ba76a2364e9045f7a1767f7276752bd00dd4413ac7c8b6170638a1c0aa7748dedce2a76c30f592ef198d4b34556d7dd75ef81e97b85f282b0fa3eb1465ce9
X2 = 144e1340d4244f888f8fe2f2697586bdfe
H2 = 00ebb6f11ca2f148b15551c3499e457f2898eaf152c85a2b2dd8b125fbeb96c870c854f8995dab02a8d64e8de52d3b6d0c4ef0720245bbfdbfd85bf7d4da2bc71e86fd7a8bf12eb60e8b6081f9a7186d9073bc2779432ea64be32f9cb4905c37f75e723eaed9552ee9b00262b378e5836e604b7a8e4600
SS = 017480f874f1c9667fa67af57085e0caf58efe194ed590ede29457b9ab452f78e631e405200d7a4176980f3f2c1f93a942612880e0b086dfe411679c29bf967eff4536c33ed2ab763bbca4494cdb56427157f4dd4700422cf1ed5cb0bfdb6941b2449af0c8b7269786a6f506228750523e752f76b26173
P = 0b6c9a474f7ade8d4fdcb62230878901f9dfa085d7b05d2b0f6c1e8c56e9901e5deceb3fd31f7f8f9d0ba9c17c04e9881472c043a9e0ad54bcc5d98c95d46242f66d1395e2456c3cb08077417b094e042ed7f071abe6a0f91689daf645e0bcb9a0d770b0f85494cb4a56b43a9d1f93530a59d4e8b2b04d5f61
G = 038fc7c4f1ece3641a8036aaa3e36c11104cf8e5f0fa8bd86ed7af31980afd46f9c1c69b132500656fc832df1e0299492649119c187cdd181d1683b7ecebded93fa1163e42a138dd96dd1ec967f4f3eb854ab1bdd7091faf5f33d745c8a062cf1645f33174ae3954abdabd5f30f43f38df13166a7c5cb34a11
Q = 02c7ea88bf94bd7d3af44c4da190df06c821
X1 = 0255ac1dd79b38c89051a9b22558c5cc2139
H1 = 0549aa5ebdb37fe505a40dd13bcb248310eae037ae56fd9dcc4aaad6ec3adba8003cf954d7a952ea92bc69ffa975b306e65bab27dfe244b17d95808b045b6818e41823e6572ba0704d8df22f9aa34fdebda54dfb469523a44096769ff960eb054e4bbaeae270d4348f9414653c89b92f0349a16064f40ba3b2
X2 = 02ad99a50057eae2741bea2b391f3486578a
H2 = 067b63b8e7faee40448e0a9669fa95539e2a3b3491b55d68310cd5955cf9495b7903b7daff02d2a8cbfe170f064ada2ab53334659cc8a058a8881b837a1333aacc3aa64b4f3dfee42c81bd11d9a47613354d43767bdad0759219d99d4f02c2230d9b57f2a283b9b53cf157f70081d50168b29b49f161e48b3e
SS = 07f339da02e4b3936b2d6cb68ab9b5f6f5cbb996aba94d0d763ef4b968833ee7734dd953f10dc8d0fccefdbf7ac8afa91a85d4e250fc0b4fdda96a3b3d1afa1033d71686dfc6d0cf337cb7bf6e1b3b4ac5b03c175c9744937637043e58fd36bc18b07dcc48b6dbde4161a7bbf2c595b45fba803708785e020d
P = 515295549a912e2160d6cadf2a34227270c1e89f3596545686d6238446f58f46e837c09a339b19322cc4d1eab1bca96bfd156de1d8dc6a59522072ce99a3070e687bd6d29ab1fcd793bfe0ff6337daa941473cf6e5c20da603a5bb
G = 3b35cfb3b2e0adf8ba06555ba6619459539f0df10691ead682aa05aba4f8cafb51d02853a39ad64f5039580f040244ee1f052c1a4be27d008cbabeb8ae5fcf9993bb088dd4194a4d4bc5915819b82d9a54665acb167e99784c2ef7
Q = 3f3b4818d5742b1330d91a869b984f411d
X1 = 1473d82e26cd8ced1c0c94a369f71d36f0
H1 = 119808087ca9431e9e4ed2aac49abe3c7d9557cdab37c2831ccfb036285fb592764656482950bd547f639fb061b729afa16901aaf219e3c54649a0b806fe18fbba4741f1a2e3522936ad18ee880fc4e1cc364a7ea549b138f6dcdb
X2 = 0bc04e20501806307c181a4189bf9fe137
H2 = 34b58f0b8e9ae0847e37d9ffdfc2f0fc57ecd753e2f43ac4bf6f6543d7c93c49aa5721c2402848ac0bb68ce6387dd986dbdd9bc74ab204c1288906e4c1716b3f9f58de7dce6b236b4a8f72e4e5af5d7116cdfe985186e06d300b06
SS = 2c045d1ae7e0297c23d372028ae10225d5664337e7964a1bb9e78a17e49e9e3893af0bb6b972f0e1be362eff2f6a24147a2e1466fa5e479c7ec0981d37aed705302a63c1a0fa4b66eab48afc887ecf8452de4e90c9f6fecb626315
P = 1e66cc3d8fd562ba233999cc789893a62b41456b3cf58f162624fc548b46cfa8b434c29bf1f95548123c68da98cbc9e8e4e129df818776bf7d3dcd71e54939bc07690e18154eb8304655acd69edea9f137ec3ed8f37c8a3ab58c5fa9d07cee8e5928271717f4912faf6a0d8092a831a0dba6c983512ac48c01824ef0f4f6c6b28fe5fa53a6ca1a51c8018aa87ff4c02a36fd7e63011a478be68604f4f3dc492ac6fae1725580e0bc81be556f663fe9944b55c108364d
G = 0de6886d2782e7d49df89995b88b437ccaed0c07f29d2a7dcdc6ea3948d131558f7a7299334d5027806be597dcfe0c2504f21cbc8caf9dfd40fb00b83c7632682ca975211eb06a4e4101ee8d0035a3d0d3fb03144a1272e5b360f14e560509939b37ae42b8f1fb4444e9017c7f6e5b8fe576702cf496c87121aefa29f160f6ca6de6c24ec3a6962374e26bf76efeaa0f74dd34339bd6a3babc2d7fc05bed252f4764cce62670a23e229d37394a8ff9c8fac7aff9ec78
Q = 0170cb2874439f1bbc4d24f4023fbe33c307449d
X1 = 003b75dbb0e509705a4e0fc2998ab78c232f3a88
H1 = 0008dab49721d647bcf35c0b98ee148da6a586e38ebf8fe84a0a2716a9b5c7fcfcafb8b003a42dd7f2f2df3ab90fd14db7d6da3a9e9bdbc327250c065fe6ffcd8135273e01edb62c31f44da97a787bb5e8cd4b2ce8afb4fde70849ca47729368c519b157e4853e2e942f1021265c50a09372ee4379c06844f54bd0cbb6e0b3dbbd097f181994aadf7c4bdfe4f7b13ff3847d5651f1bafc11175e83aba02f071c9ed273b52fe629a9b8bc788396402d414dd64cb19390
X2 = 0086173441b9a37b2f44a8aaa65c21ad0842a597
H2 = 0a94f2b6194195c924a20e1d0a72c20bc0457b5095fc725a361896858ce0d7e21f7ef3d8e24efb8ef1097fea8b1f2265cf5195f727ae259bed644ed5a05d7fca863242b42479cd06458c978267b9e2646a228253a8c8d0af1304e5cbb14b23527e4c1ceaa7636a2bf404ffdda6a96415f34f0bc6b083fdd139377980add2eb8d37afbc5d39ac962ae5eaacf178cc11fde4f82cf9241c9f3464a2fee2325a9a5fc8dd3a2f4e417172c51c54fbcec99d4ee1f7ce05d8c3
SS = 16a154628151418178bffbef777697cbaf03be33ea073b98a19b3b3bd03d2cf234ce0764915fb6bfc4d772fc9a2e4fdd00523a0aa4549db890d3ad3bbd6f0658a4ff2fc02c90eef05bd9954bdc71fdffa5e0a3baa86cb10730c1976708b51ba7be6aeac80368aea65bf8d20f9be4a9b3ea35b9bcce1535dfe15e4b599cb01215674f70fc0127bf1a09f80683f61ec636bd0179d2bb40b69b65e186da17464efd56dbe587335faf3a3e1429c3fba483e3d8ce0917ee65
P = 0a8f848171df45de54148fe9940d4c9442632d2b5df58aa96ecf96c0cd8bc069983aa949fb15a3ed2bc6771b5c6524912cd21554a9ac316347d98661c35ae29eb59fdbcf7f9b833ba5135d56ca391fe6eb34aae4e6f5dd
G = 08011029ed9477491894e3d5521c25b0e631be889e49b59f10246ac34d6a93d99ddfc47bdaaaa6d7d1d6ebc953810acc44e6bd4923fda49a9bb952a7f4ae09182673cb4cc427cddafab57a57996a5e9df765d893c5ff50
Q = 436b131df3f90238a2fdcb0058ec71bb4f
X1 = 0210c8d4fec517f19993fbbe664c6d02a4
H1 = 083cf53f7ca70b11e31f18e9b0b25866b85682a08a4ba1ace15debe3c83a54c734dd26d02beaeab9c6d800fb2c8d66be5de22beff5e48767920d8726d187194322f14ddeda947673b0587356d01854184314bf2a0c6ef8
X2 = 153d64adfda1365a7baa0fd0ba55ca8e2c
H2 = 026b7ec0ed086d8b16ed5c39619974e87ccf877dcd5e0f44b0fa18fd7ffc56505b89e69209fc012482ce698ef27c64e4dfcb5d34134ec6bab54b790c80a89f098d20492ddfc5f07da2baf891d7402b75f407866c655d59
SS = 00a057cb6938e30a064946375ed2f95f8f7c684696bbf5493144a8757be28dc8a71d4232ed142979ed4f6d859f9d76c09db1c55a4216f617a31c9c47a3219bc3687f909794dd01f5000a8060232aebb9e0bd010c13ff53
P = 2ed8e7aa15fb2e49b69272f8cd58a13a6d02d23827fadb235103c0bdad1b37b131e12efb9e3a3ac9c5cdefd579d39f5c8f34678cb232182ff17dbe0d83ee5805de8342c8bd974dee1d5439ed930d8170bfc2947390b2930b0bfd1c5c6fea5af8e53f966370607eebc02b260f7deaa96259579bc2215fca502b1e2fab4230c464e2cdd66f1b6450460c6bef11
G = 02e68bce10621afa5dc74b5b987335d2db0f7312be8405aed98c27228211e9647888ab130b98af8e0499dc0269e57a97b0a6b1c2f4ea40f20e6e2f102bc56829bad504e004e7ff4c729c73902f023ad8162f345e15f2ef42da802fa7969d3ef8dc650b0fb7cc75ae38c632a38722bee3e98fda1a881f1b1c86925bd918df9dcdfdd3d68174decd4e5c5af43e
Q = a4be84622919ed5b992696dfb76a62be805d5d44546ba849
X1 = 2834e8c1fb9ba8bb7b5d76a82412061629a237554068f353
H1 = 2bcafeed33c85d28aeb716d633a89c4cee16ecd4113cf49ef6440ebf3be3240c9a70968da7be28ee814258cd3e230b69f1573924b7ed0ee58e07aa96cfc084ec3d8c5a805775b8a56d9428e48ed548a98f5703ad006bfed870a6510a011ffc9a3dd8aefaee0c008ccd1603edc3265149f21601f9d7e5107d1bc70ecdcade06d322aedc6b583bb19a5730d5f6
X2 = 12dca3d3161bd65db89bb3473b955470c43831541e4a31ba
H2 = 0e125a7d2a922ea388e22a53dc808f6aa2e9365baf07ec2d20d5295cf6fad7696ec901b53e54c940531bb5f32810b86fc0b5cf771240ecd5fed5b1d6f1b26c0323ef68058b062da897694480363154a2467fc9784c22e918e48535c7ba398b39429639dff49df99c65b67ae15ce4845f1c5c610c851af0e80c1df01d7a41f47825ecfe5c490881e0561e1149
SS = 124cf4c98e0a63cc21e66675e63c806daec801eaeec7847a01c3993d63e9cdf58629a8e6cf51c957f01a7e24bb75eb2f949dd8f0313216d18837350c1bd464536e7d13a47d1d9e8e0d7ec591debdadd7a3d05cb9836f8c8a6cdd3ce159ea8df1853b51901e5491abd33bdd646a196a2a107ee7ba2fe665df5b9d414015fb6d7be20c40934e5bbb354eb14bef
P = 0f3442e692486d466e0b67ab0800cbf151ecaa863bf56d2d00c88823f67e79f8dca3c5a49aa8c41a8ff05ced822273a5de1b26aa9e3464e3558aa88f7eeefd6cbfbce4b8c408f3eb4fce66e2091321f35262c7ec87e6134d34fabe50f0215ddc09f593fb88adc6d8475bd34053f71d59e9533f1db4c4cf1b1ac85851906585ba8c74b9b9082caf3f
G = 0eb64826ea6efa4c0aca5c6d4024bc05969b6ad94531f2eeb7470676afee0dbccbecd8872430a7ed08cb3a1615e569276a482bfd02310107647173d9163a839836d634e80d143d00c34b5c2114a2412785058103a5b69021be255d3d1dd1994357a761cb45fd9a1092911a15c8c342663d16d9956ff85afa45fb05f0d99ff17b33ad9af017889dbd
Q = 1aa1ecd1dd89e08f81fff179d41f692ed5be8883
X1 = 0102b39979a9613fb3a36c1d6928e9277b21ee41
H1 = 09be8a88ea93ac99dcf179b649bed30e74bc4e75429536ffd835b1bcb6d05b1bf835385f13255a5fbff4e5d0fb0cb11cb6c007afb22dd9e1f0333255739b6dec3550bf4568c692a8b40aee35c745261bc2213f3f6178b0a45461a4ab8fa389d479be37cbdd9e2cd4b50da52a195c1e86277fb2077eaf85c881bda2f65a4b765feadbe672ff16bd5d
X2 = 0ba3a29c055bac9fdfe28641b4278f01866537d3
H2 = 04608fd68691e52b45604f4826c88f31cf61de6ff28312444a3ab195483cd3b942078196de981759633fcbf57336dc17285e3c54ce9686940732a9f654495d1e0ab56f4d770b5562f687dd6313db18c984210dafb62831b0702f9a66fdb09eacfe2659dc77d9f9475ec6c3d269fad74faaa930623c3ca64e5e6818b2f1e379c8e02b560f5fffc2cf
SS = 05302da11a34f479fa547d9cd3f2c3b19f3c708ef06b3319d2809ef876ca872e715836ce7f59cc381bce710b37fa49f7439471cf191981e94b0bc6338c6d4155abd7cf3fb45f6878ea7221c6900d1bc8deab859104923db686d49832ecae0fced1206232952cf059dd1e7cbe778e16a99a8a22daadd7790291b7ef93218c82427a4e97463270e2ae
P = 0105404e665c3730689c8c995573fabb32052a60fd4ebb4713bec880d0b81540db9d41450588232e49c68a2fe13c5863305a1a696729275761a8d6010319a27085a645d3e5a5b83d730ba5
G = 00913963865c6e892e66da909f9f87bc83c78978f1004e3acfc51e163577f554cff8b05f6e0a7c80e2dccc433868f4876e34d29ce0d5584f20a7a41bd234ebec07bc020434fc632c251447
Q = 017f42efd85651d6a2389750d7ee1444c357
X1 = 00de7e7f35fd7c24e57ecf0288a154dd9414
H1 = 00638118ce81ff59706478d98bba899537a83a426f656395a3e53685e02d9cbde86993ab52a3d1dccc6452c1aa2ed9ea2fb13357de694211105e84f1dad7d4a82aefd0c8a008c24a52f921
X2 = 00853e029291bf11fc1d8d292bdfd354c45d
H2 = 0018a769d7dd238d283b3f9e99398401b31bd48f981da12823b4788a8644854423263f7a7b72d0eaf3c1ed57e596ec9259de928533b7a72c777327b9f8e17c0995f4152b360e5ca3dce249
SS = 00a687f668a71dadb5a822153adf57ab555b4ac85282944567772dbabd5028c86b38eaad51b7d8725aa7e168e881ca571cf6fb68ade225c7061757a319e80be5159567ad0cf2c72d13c4b9
rnd = 1

409
unittest/kat_dsa.dat Normal file
Просмотреть файл

@ -0,0 +1,409 @@
#
# DO NOT EDIT: Generated test vectors for DSA
#
[Dsa]
P = bfcd86e969bfe7a2b9369d36b84583bbbcd7ff619c0de059c5a46befdfe901bdd5a357ac8071531abc128c21611a78aaa1efac041385c14a552e1da789565d8eddf2ccf422c68b6aad03f674200c580ecf46aaf0f1bd29916f0066e67ecd9f111ce4d4144c2c8f7ffb7f5f45dd64cae1e48827913e9d9df45aeea2a015c2d1a5cc2093d3f909eee06b40059102a4237c0eaa6ce9c69333fb079c615fc9466720c43737c0ab0f1f88f4a9654308d2658321e7ad801e9c1e0e1ce6c9dce32c7624d802fd4708e2dec9a7b3731095a6c8176c88585a2b0f34c82953ba333f82d617751e1eb7a54a24bba957945897fdfe3d181f3b9272e79374c531d55e12b078da0834937e19c19e5e4455910f2bffe5f17e39fcf3103e5da601443251ca07dc3a9110aa1cba91369064e2aea662237bafe3461e3cdd6a3790bfaedc92b0642cc2fcd6302be2ba52c168b58815568324a61cf5b17bdeb32edc4c28331bae5361e2f9b776d631f537b690ee28341d8ee05cbf98be3f3e9b313de5ff3d09b22afefd68062a0a257b34b3a7b9198dc9e9e31bdf79efd1e8334d596787b3a14d0f48dff9eba21a15b819d68fb1883c51cef0be8fdeed21b97e92fe80f9f1e866056b23bd662a6386eee237c64e189758d6757d77658bcb25f4571cbcf9b3576c249975d717441623bedc1b632b1e4b6595d1b99d426f08756c1011ca46a2f580295c4d
G = b12d3b1e67c790d360f29a54edb601cc8bd13e66ef80c7e5f23fc6fa3931d7fbadffa4b6e33b4641fd52b5789e3c0958b53cb19a66742c5e49ca7378e68980bf3b38f3db0fe6c3c6b114a26e880a897511b61beb7ef5edc10033cc4bb6a1a46bd14f90084d10d5d4cb5edb992eb96cc301707dd04e0e3b2dd90fe21babe65ad4e9b904e8144aec53c28d5129bda9730ba07b669a8a17649e3312d37da16b1e3bbeadb535763425b94405a68459d954aa99444de307fa483fc913443bda98645426a94598c369d3aac8bb85c00d12080549d5b93f3751f00cf971c79c7a21c482811ba88c7fae06140f6b906205cce21c58047066869a2012032f7aa8ad135721749186dd5936e042a87cfdf422e7329534dc1ba38d4094bb7f8b9c9b94ca4e373829a3693f22919674ed8021ba365c7a64ca196f172ab96e8515eda2330120e6bc61ea22e82e5bf7810a442ea362344304b0e825d6325d6811d6fe5078749454afa4cf00d69a9652c2dc3ff8abbf348f16c5e0ecfc7f2e08b15d8e349044f266e9c383371b7305a88b631f4cd3ebcefe6ded2fab7394fa99cb526c9da18389f0aa8888908102912229d6da4ebdc784c9ab5b1e0d116874ad85feb5bc17faf2903cbe8463c4cc9361c0b6706836c2b31374cc9382f58ba8442b5725eafe372f92c830cd1c7f9c4e54c04adaaed1b125d4571b55d0d6ac0c9fe40412c3b50676e7
Q = eedc4e2543c6dd9bc15c03efe60b12b8494cb6617a53ecca6fed44028bf093e9
X = 6549b43c3287a8a0a9685b70f85c070def5856a8eefc863fad2dd71d3e44d089
H = 2fffd2348cce1dfd45bd80edf01871adac766c7838dbf5fc579570bcdbce7376864995f44a230bc00ab78f71843a99873671fe903e9a752e346c1a726015100ea5197a137dd9d80911bfa3cff71c1023426fe24b3725451d8f47d7336796b907bc4e1023366ec7efbae113eab4330d0b7bd1cff91193d07cc0ba24bf2dc4947d0ff9a3ff169a82b6a362c7952a67d51f47a89c9b8aa6cd32d67d125fa19a5fcc86ed61b9b6ccbc6391f8b04192dc6724214cdc3820e0022c7af51891e2f1d3b1c20765c91d22d4b18f71eef254238ff5addff12027cb11b7beb9d24e45d6dc0c2709ac4bdf6627cd30ee335233c17588c589d9514c77b4678dc7a71e12556dde55a60d05f36a0c3bb5d2dc38aa62351f7543bc82b8776b2357f2a7307f43208c589e5c4fcbb1e309a2ababfbcb7ec68f2c9c26e299292edc349f2ea632c8aef7368a8282734a56ca8cd86dc600aa104e60607c49397161e1d38190842d7662305b8e8f009e53ec96365d755bdcacbbaa44391cd2654bbdd741edcbfad8e45eb01402262ebc0123be01a0aaa23c7206ac0772b000b658710bee129af020e29f13387482b4d35d2423ddc5dd6a1fe2f53be2a9d08e74512e5d851f6f26e938a7b38d3cb938b923350513d3c2423cf5d92356547147fc772f9e584d71c4fe99fc471c20816ca66f440368cb3f0cc219ac3de4f314b650837c866685148d93f77cab
Hash = e0a04e7167471c7d761e6e60aea2c3863a41d3b4882f9b85bec7aa5493283172f2149650a854239067f0480d7b7d8d76
Sig = ee1e087dbe36d388da9f67e01289c1eb3e1cbb79022d4d41729a8173ac9a5250dca0656aa3560d6a366a720a268685e5a2076887de931f73725057c60cf3bd58
P = da735aac131e93f0c96986188ec3651cb9b7a5b5966d0e07766f41b2bc70abe199f85add3943bc72ff7d18ba3e860af2e51bae72aed25f89f9ff28e6aa8fad43dccf0b97e67e458eec46b2bbd2ed11bdd2e4cd9ea13090460d53a7a159f4d0b585a8365b04210e1c1910fbaca4f900c5e02e9b7a5a5852e9714947817a9a534b978d332bf0dc3d229bdef28b615e46ce9a9c489529ce025eb45d9f67a680cbcfd0cd97eb2aa7bf692dfb8fbd9b71978c8dc458c39a78030e45473b5da186e0f6f44014227e9bcf202383cdcad2f2b1fbf85513a8bbf35d221d6b25dc043caf551378f3b2958e8006191f71f361e4281e01baeea6e7e5dbc2dfa8626c07c03dbb5d879177da9a0d85f77692b0b8a9d8f91bdba2aadc458ecf5bac58f5eed48623d5d68a1b777b37013a8e56e2e836c0a0ab41e116a00b3345f66d70dd142346067ce75a09e8623bb769d72d21ccd6311d846c74a60d9f4487c33c009ee325a66ebbbb248ab44e35a5cbe4b78198ef3a8a66eb74ccc13bc4755ae510efc5e6879b
G = 0ab9b38440cad75e60f45cf7027b806b70e5a718564490f53e5c2300f43ac6d1e6165572108db5c7d87334cd865048322acee129f547d40f7f8d4a1ddd099fd340707ccaa6e3bb36b29a12a73feba6d4ba5b370d8e7b92e7e89a4f67d5646aa15e4c3bad4ee9dd630c109b640a76125cea67d81d0a00af1d1a41fd6ecb326ee4b040715f30af4afa73396c921fedd76f60e14ae05ece75977d418a891957f83ac3d5ada259b08c6c649dda1e96b51205f05525ed8da0918f7cf9c5bdd26b057d09882e13f0f2f840be0f0eaef263ebed675b01a44d0b951d214fd4a31425bcbff554dcaf2b935d733fcc7b73c4983134a262d34728428cc3b5c909c7ed2d0d29a5a7df455ee885062c0a7d9beca94b7fcd8a034fd34b253858d333ac673c84bd48b28532ea146cf26301ebf3dadf02f80dd3ceaeaa4b40003063a23626007f1919db19fac445f2f18583663cad3504eb69090513e88f390915f2e0935a0a10eff301d2d8406ef1476ba03e03c5290a2c8159efed59bfc950a6a56b50ee50a7be
Q = bbf04b4505d070b86d4897b4d49bcaade4893da33bd39df57d3047f1f2f20edd
X = 541f8892204fe960b84ed0afbc95fa0744a184873392a001a43fa64a41d64ab8
H = 452682e0a05370eec57c9c8a4e8f918de247ddc7584526d31251c21333d1154d6d76f611e9cf0210b28088ce9325ee8fab5f2b353b39165d6a59fcae7d727050e5d91563542044a5087824c5c88c7a709faacb48e92654ecd25574d493a06e793f12f4a132e75dbb990f3eaccfedeace256fe6967bea77deef87744e89b6611029d55d521e8bf309aff54f981d9c8dc7dbbe0a62a42149c16cf62e50122274fbdb17fce7e9ad2ec1564e3fc975f4d4d182d17663b3691872b6be6ead904d845dc59c00e559b46a311c4925ab6f5769e7c1bafe793e84904bbeff323ec083b35f138a47db07822aa2b4b9f8bac1804300e24bbca41926fe66906e443894ccde2cb31f710e0ca43f00373a0f2f1254a3f0593bfd6745da8abd3998dc7eac35e158d5f196e1a3e33bc52c166fa650b4598d91dbc077297dd68db8f288f0633034e9ec9f3910a25a3e13ea90a3c2a44c40eb45badf21c839800a8f1e217ba7c605d1eef3128f117aeacbc1054e902a9c4b568ca3d73ea8edf0de10d182fe20f3823b
Hash = d3a723ad7e04fba61b8381ed6f339f2cbd68f8d3e0090053651e499c416d8147dd6b79ca88840257ecae45d224c8bec77ae35961976fc5969e5fc8082c67f4aa
Sig = ab3b6b4c3a613e1304d8acb1966de455c36e167b986fd9feb097c03c8ab3c3456f24ab89d11daac24ae848f1d783906c58dbd6995946cc9426df36a9ce2b7ade
P = bb8e7cfbdd301c3f3b6258c0f637371a99aa82c7777741dad4fd3d729f23c1b5bfca4b228f94d18e643a65acac23dc4ba9c035ee6f7f4720b607dc44aefd0b9938f919714972a9cd702a4cd3e93932e2bbbea071fa586600c6021378f35eab8fd502f5bdeea2f78e32205265e83b266c7e189b9fdcc18e21d6f0f896321f4f6be0fa5f8691b60d2cfa6bf996ad2925e6ad891b3f7659bfc448ee0db4a9b46d02122c5323767307a85bc2ab6ba4f6bd1a7012899cb99eec6e9383b08b6b1deec6e2b3d80d756c9c349a8a6d74ed95b307c1489dd9435af1f65733327679bd523eefce6ef7da7c0d3e4c8fc5e461c03529b2f3c42cd3245b717858716712a08a2f9ab8e6774c7eb4624c5da63657bc19855d67d12af0fbaa5070b3dd7f21637c35434771288b8bc99c3a4f306b17f8192c57fcf84bfcc5fd46118fc13c2ce55c466f806b06afac83be8fb293d0d7cc43e4a7b89b2cb6cab5eaca067081debdeb144db814d26df3ac1b51d9fa44d278901086afe2ccdcef4f10ea58b6db5a325b19
G = 91cb104c807781615cef096b8fc6162efb00107fe686ed2bb03173920ac1cdf56992047a61a98bbe206b106385ce08ca16f239fcfa2d8b4f53b947e2deb6cab8a7188369f47fe979ccdd234850aa928e6eaaf647d114e33730777ca5556e95863914c957635b391ca0a01df0055435019a9a24f874d2c3dfaae0b145cab2eaa0d1d2434aa5eac0ef28b7c243244f40b41cd87c742214a2d5a4601c0b6b4023670f96e17e3afb2ad2f2301e2c593dd48f6139e529ee31af21d031448772e607417145068e22551567394f65ce547d149703cbc9971b88a6c861e50a9383c3a2ad0410e53c104e363866c57236295488ad2c5fd50051090dfa77598b78578bd2c8b3a1cc773695d7f3384887715bad64efa53ff927be92942f80031710ddb96e384743550feda57c260ceecef26a2917a7bcee552a2153c11c9f52c0a03025c35a27c07a6176b76e4e19953eade8faa3b7d2e98c327f753db3842f07592dabf1200b1ff4de9b720ba7cfc8d415eb130a7599c610bb16cd5f774c009116d9f1949d
Q = e6f67f441d6b628a46e397bda29af2c9eb1a4427b722956498a31ce60be6d509
X = 30eecb713a03e506e180ee04d1d66e7c4d2be6577996ad1eefc280b217c12de2
H = 0f67646b9f8333e90c39fbb91798abf2852e2c765f4ab50f8238af43cc6b23b1cf45813fff70b1131be2d7f5a4f517178d00485afb5e0b6e4ce4889146363ee66b3dfb4fff4cbe7a1c10b7ea0d1e9c97c3c3796ebc093b9e4a8de5ea09b4eeb4e03e403aca3746e3bc3aee7c84cbc08bddc032e6bd6e3dabcba83fd9e5e5142dfb799425c800cbdd7a16a092e38d0eb5c3c015dea18162e7a1aad0f51e15a24ada0d24db9ef77dbaa8899d00ef77163dbc58e4d987d594d01a2cd0abdaaccbb82ef0fcaa42c332ced65992881560c453abfaea6488ccd795374a9c17682615d4e2c7f19c132b1ceea5d856235e10479000d79d5285322b78a72893fcabf2f69fa3d4f162dc0ffa955fe860635164da26fabde0d6f7103306bdbe655641d416487f66a2cedcefce858850a25c6445895234aef4e0a88ee1056d05bfc5e865b0c93c9ac9dc5fbcf4267a22030d2a5b3c1c9b780c28b9ce9ff2591c1684c9e4d123d218dc2020bb3b47fca48e319952999ed252c139461ca1975b89b03e153becfa
Hash = 2b235e93d8d70f096da69bbdc45f76a6daf76b7471b893a4337709180bbaefc1
Sig = d7785af5dbc471255d047ecc8add00ec237a60371155fabd08b630faa848b2016246fe9255063afcb25fb57d8bda5814ffc07e6de450c841d4ac301c722d6499
P = e1df13d314ca7b484d5900d7b2a71d7f4ff290ae4ef50b61a1ae010fb71b3a509f9632bb08f5831402e85f3ad61e16eb4cf61f3ad9891332c09ac3d84a79544ca2caea837400dce54a46826f9954049d39856c5f1684f0ef5f95d1fc9f3abf89b5521cc5e5c4a5c18d1ed999a3a7806da3e946a517d37f5547a613f3c744cb0300f3a3f81d39ddabb5ba31bebc7b7c0ffca4b8429603c9d46420d0f271df3643b84b5b862f528c49a63197792ac01c26ae38c10809cc2644c441fa42002dd72dbaa40b6fe5d02015fe30b48a252f0764ae6b682d49874a312f10aa0fe59b503b37cfbcdae6e98383329fb20b4afb53c92d620277c16abe3b3ad3d60a009f6a53
G = b73472f9b30766d4defb1f8beebf9fbef4f44939d796db6a4ccffbadbea7c54461dde7eb092bb83d7136d762678fa358f901df57546bdbf3bbea1135c02cb7ee517750e71ddab4f1c717098cd03369fd9bbbbdaf9f6e98a627b88ced0e9e3a4af1ae2a5d08684c35762c5ba0a4ab29ab1b22bf51a78d35fa533b8b79a0c7a483d009a42643632850dc6e94df5bf4354cbd72182143d0f351382112319ed5785b24abf1a50be82d065f4d651b49d33a4d6b61328eec943986c3dcf2f25c78a45a063760d0e60e11439df475e9545d4e33f2932ebe586adebbb4250b2e093872d3037d57cdccdb596b03b4484b2b88269b0a692956ac77933b7a21c7baf93ff882
Q = acfd2e896d3076cad5682a4d56cb4f3a76b0d88b9cf07ddd3acc1b17caa62dc9
X = 8fc56e00a1004563368e3a4004c3a1708799f70b7b710d87ef030e59303da268
H = a29a195f1f0b9ef9da50c6e646efc95d9e6247b015c23d30e933d5b61293696f13c517aaa5f1dc29cbcbe1fad0a618ab06e7ae7ce0f7db2de6c8772c70fa6f70b6949c5414e9f5495dc4e895661a5572d32831f48266e53eda3a4127fb5ea3559bfb515477e478df1f05eb4970e6c575e74f0d9446af52463c3bc5d2dcf0a35b1347615886ebd78327af09c8b2147485a24f9fdfa691a5312ea09e1ab43cd18749cc9df49773b8ca0a9d66dfa555f7f8c4a14110872cc4ff1255388f3f821e2adab9e536f3f509f086e5b17a07b1043dcd2e3b6f94c1d7a11ae977bc792d15aa6b7e466bf937e9061f2c5d07ebc4b5a04d154f263fcc0b11e2b3524da4a92803
Hash = 5f986c83c636c372aab49c714aad9f92ed38419916ed4c12dd5c613eb2743962
Sig = 5579f05ec8c9bb5d8f2c4d536c426d4fc0a6391e66f999bfcf3a5340bee0deb63e3a41f12b74293a034af9450f7cfb87dc5363899a0211aacb183a45d64477c5
P = e814425521f9b6f13cc65659998e890581e8e176a0b8541dba648f12108b1b56e15b91d3ce83cea9d6b0a9f0f89981b400b28100786832fba89b3b308bbf2ceb85c9746773234158ed95156901c4944c91c3ceab2c23a51119e986e0b61114382ed00834563a19f29100ca25d07e6082b5c513f702e1b2202c19f2f39ed9f96a9e6e6cd998e259e5733c8cf9537a201e5743e9080078d6f546615e4970096a732156c1d3c6a8ea5948eb5d3509c513c32451dfb5ae6b20a62fdb7eb341a2d8f23b95a772223502be7474ac1369d88ee13a089f8dbfbe56af0d66cb33d3035825a3fb56cca25090cadc17b224ecd5d2ded22a4eed3ef9025c36b8a6a1b533c997
G = a9b17ca19771243b008de48e871a922eded1f8825439d52de217fc89cb1b19d1238bfeaf11fcf7c7be0f3bdc758d698a446fb5f195d582bb65590e3afb18db45bda45dc35b70bf00b6c2acb38bac45e32aa82cc2f6d04fc6e92d1f4356c922ea28ec0d7a32af164bafaae9d67958f5bbdda1c9d816de7d204844feba2455ac4bc1f935cba0add453bb08aa5cb37e9317b2ab133104fb879faf17b09b97c43244e30a94ade669b8df5525c291406076f9b3c976aa6e43e8e9576f0ce34cb1a492c84a8da3162a1917d4cf787161bc92781b55e6cb112b0fa392557aa692f8bacd4b0352c7a42f3c54eb9659d236103a07a7bcf448790e9dee3fc84127a641fcf7
Q = 9ae7d6634c8aafb67f78a49b2e2b95dcfdb768c635da46f3be10426d4810d1f5
X = 98952195bda5906b9be4ee5960f0f86ee0843ab198ec56789e535f02bc89b5cd
H = 62d930b76aca97f49a4cae39307d7f88c2069c86a0f59b2ea1edc9da2f67ded7e08d66e482faae2c12ce4310bb7152424633952d07940969413dd457ff82efc163b1d99d1f33cd01c81e53f5a277b1072d33bd35415e1a74210e02744d28b91d24339cd31635d7c82a58a51b966218ef83faed9a2673224908f6d6f9dbcc9dbc156f0eba60796ede6fec0bb9e5c5a062402e698ae154c6c6b2ec27a2e5f74d5125d25bc3d2e0e446d98fc2cc75a2271c25c5b14252eea62f771d7b91bb54edfa1fc8e8584c4332b2940462d391461ca4e40dd28c62b29ffa420c38ecec30847d2564a1e4ca94c1c9dc03fd1e9989ec888fa191fac244d0205bf1fa6f063f78ea
Hash = 7367bfc4379be6d634004daecd171256932b756846aa20ec86a2f4856275ff36
Sig = 882b20036ae52961d84fa5fc74aebd87102eeddd96a6be5bd489933949ce05c94e592b1c576fa119f36d25b24681a33c39a5f67323bd9f7f9b6194b85922aafd
P = 8fa7447a5ce7fea35698e07608ffcb347f8fc2c3ab9f1d35987110846716a2ea02f473c5f6656bd58be25dcdb4868f2d4e5079f76d9d5c377949e7bcf7f8b3610dc67f76fe30ed34fcc331b626661565a45c78b53bec0de5b870c632c15f29174f1bded3ca768d2b347e131ee75333ce489ae3ccf122bb9b2f98f7ac69fcac31b7209108b2997e46dacf8a51d53315b8b63f7d893dd377ab418ccb79c283d6ea62cabaee0d0c31bb4bdfa7f06a6bf752cccc8f6d87f8b855a70c1dda625c71cc5be5a20babff48befe29af6b96231f52efc6831e08a0a38cd7e3bc7e8b84d6926cb225cae15eb1803bee89042249aff4495f8f87940672aef787f8faec6a6d87
G = 191b8dc7e3a3babd01e87394c10a7724d6e8a579cc92a3cff5a98e662782378ca9cc6a2097531c780f40e38a049da82e36ac0fcd626ea83438f0b6bd6d8155a3ab7484a067e9a6eedd0e8e42b835f02e17d465dd12d6d0ba8ff9145a2b03ed927c8bba97425ccf924a177e45b4e14a63afdf99865f7d6ed2330d9c2f6e267e47f7cff47f4a7a3e06e926d5994363faccbb2a1c3ea1117c89d8801669bb84b46764f84cc29be1041875f01b4b8a0355e4dac01250eefa191e18948a89ce73c043734d0664bcb3cebab05945d6a2470240f92ef5b406043a96eceb2615cd9a8ffc3f0c42276c2a9bb9b3d9a34b067bc3e57acc911680da08ec06aad853eaf7289e
Q = adbd6c5678cdc26c70a48f39408e468e0ce677358cb9b922192cde07bc7391d9
X = abf5ae76ad2655d9e8d757c9e5ebb0da6753cf85472aae457ba9ca93bff49641
H = 5bd54b5aab48b09bd8e8f8107c014f663f5eef88bc5ce431d8d838637dbe851b2ee932e7a1ee88ed62d6c5d71374a104c0f0630392dc8380d43bf19efad8114bb1616081d2a8ab03fa4587c6ca80955b51ea1571f5e4b1d65b1ee0313e1e10d283199dca619ae346efe6c5f876045644ed02f7c7ceef05369860b5e14fc0b33649995ff57a07f53fb44eb10db1b7062f1df6f793af5704c5aadaa75374b3fef8daca5dbea09e9e23004fb020b28dde823d9b58293f34ef0528e140ec4c2b80ab342372ce0ffbbccc674a37cfd561e08ca733b1456537cc21be29bef2c95a7f2f0441cef9dbb2fee95e3efa7f85d1da2f37dac43eb6512e711f996fe0d7dbb4e2
Hash = ec6b3eb3b1efa0acaddd8cf2535fe8c82062f130a7f075d9f12d3fe6ce227b
Sig = 1ccafdd5e3edb255a2befc82c103ad6644cdf292bb0e528292e159173b35ae659bebc606a929e7b6d54e023de3ff71283cec1512d9e9620de5a0f1d6c33dd199
P = 9e8312567f81e590ad3987c9977d39627dd44b5aed02cf7310b19f7d3522ae6b03ed7f3c8272d9c0f855e2af39f2737e06dabda64fe78023f8ac305f0f9d9a9ab40e7c07931f4a00375b36d842473c60587b0c7c4ef913dea21bed9f8881c1c2e633d7d9fe80724e9ec1941479641acd455a6edbc2672ae9d006a92a371a1f6d4d834d84518ed3479d6da35154e3b3d18dcb907065aba1a9148e2ac89112028a89a3c47f611c143c328e36b3e60ad66fb2dd7014ce4cf2fb878af9368b984a8b05bb98b8e7cac829ad6fc8b55c0b7cc9751bd00ca6dd4b9146c41a7a4ff7e217b3093803c948e8fabb4f533604afacd1cbd37a05a2697600d99e5b178587b0f3
G = 2e72b48aa445f0068377e4486b4cf5c54368045681b74ba00ef5ee572b0497ba59de77d31153f6f4922549f38542db70511c639680b6d4f1124547c2f17796316c64170d8ab33ac97e4c9784884382f30be0111f98bea9db9a0f9456a9d7383e447f2a180e5ca85a651304f4b1659a2f4ee5ffac5eaac42aa0e85b3e347cdcd9e2a0d55c5b233da52c04d8750d41c3efda50ea766abd84d88d1dd7f48d6fe44836a29c0df2c90d1cc57c03f71c6b6373cac0584e10adface76bbba7bb956e6aed68f349549f1f3060e0a79ecb988b2e5e8aae2f45089cc6ed6e8b1a05c8582b7da585fac23ba936cecd1231f94f77b5e85b4c1a5c5f29840eb03ea1673b5d20e
Q = a246d14c2eae2152ae21b96fb1f53ad821c9c5c36f0fa15fb304202ae2606951
X = 522a5232ff560633cca7d229dd12b2af6b68e1db312e5f0a3db3cabb12d46cfc
H = 1621b648587ddc18710d18c0647fb295c0d7f664fc2100ebcc2d57f14a7806e69f533b4435861047eb3d1cfa7a7eec85701de15c445c92deb1e671b02aeac0a5dc32519fbd2a218e636789e34a5c8cf15b268b512d8f8fcdf64ad01d7d25a56afd9a08f1054e8402f6bbb8e796ac795f9c8cd56fd898d51563f1374d1b9fa759149ea68e841a98ea8d20ecdecfb3c6972f79c3b276471c9ecee4f7c80c0bb5e4a4081f96b8c581dc961cd717f394903908b10f4c2352b25622d19fe94a530f6e5440dc13cab7e4835711217e55514bd1958f15f0d49faa6ea02aaa9edf1b965d59443faaa33a551ccbddcb821309d0b4045d8124cd1d23ea0e88d26418dc7c9c
Hash = 011a15bfb2c1b2c6720de8f854843a12e2cfcb5af17a14702448fbc413e94e1dc29d180d5f6e1a3bc564f2c282a6c2e3
Sig = 2b5a84979d339833f51ceb57e0c6dc61efb4d082999fa7643f934d33ecf44ef63952832e6d5aed033ec634c69db31dfd75be5a358afec48b8e51c6706949e8bc
P = d55c7eeec6f95f4fcc7cd234736dfa54afbd8dc405de91ca01d39a49baabc11bdf27e4a18d313f59c1af10cd5d86c8d498881481ea625cc9067e2c8dfc7c5116f4b7e0f45f8a8a670093890a47421c19c6f94733aef1031b8bc56f65ad8ca5d4d0f6b35321f30e7098c91d90f0df72a2f17179c1b269e55f7c212139d21a6f819c23b6c8f145b5c4e0c9f2eac1830f96fbf90f3ea25833beda514053a2372a4d4dd375186a39f2bfc4908b69b6db3c108fdb853a04b32ee80c0bcf47081bd42f8d80c1051a7d580c742ea9afcb9c4b19aa581cbe214917a791845340b03849f877f67fbc69d8952c09019e3d6d78f00332664f6c30d9e13e94362a4178c54041
G = ae8448e15deb2870dac3091ab25e3432b75065012b6cd9fe8be4796cbe8bafb845451c669088fea2f8784021b6a85ea9bcdde1487c5dda3e66de0d80e67d42e242e168c9161b5d4dc124227e6cfea249ab2e5233d6ddb80e8a7bbd8ea7c96fc34207e0580778a9ce92da0fd149045bfb79d2c291f7b11f29b83fdb9e6af20ab09a10cb19f090f036e67fb7a2b2fd81ecadbd90295e98e95bcfbc722c82b77c9c6d239577f02f146dac006dd1abade601680a8c86596190e8e50e48421023f454e5b48d0a3f6760ab86b711d5e258698a970ad0e0a15cd353b13625d35fee67bfcb0e9e5b410056ae4e3224adcad193954eeabd6940669981b444fd896eb9e750
Q = e8d31dfc54f609535daa1177afa422ab4289314bf5d924a4663b471db44f2a9f
X = e26e6ba4859be804819d20a3ca896fa1108f2a64808ad68e96c387abd9d1c8c8
H = b9de3719da9a30c7cfa39af68949899cb4d94a3956f33506f755ce729926a8a576a956f51fc310ad9aeca0e10d3145142b0125959886e401a1a538300492bfeb5a70032c9b2dbb1219e290f8d2b886e0e95006ab1883ae47799315142a1d46f32cee56e67ffe8b1097eda82af13904592a2df36d3fd01c6079a2dd2206c643a4fb1880bf5be21bfdf8d6ccf56a513d3281adabdf0e9afa6c60ff19d3a4dafe909c9f3a024432a9712a1e9f6563548c6efbda8eafb08338f5bef737f159f402c2661957ce99042d2c31e0c5a0e03c8263f6ab59827181b78de91124781d46dee7ff7c93e58e7817292481c9e3d8473c82b5c7b236347e51ffcb65871fbdde134e
Hash = 0a7e8c4f9e23ce3ebd1994a97de5bb6dcde87ac2fe194a110322465b8cea8409
Sig = 5412ac158fc4ccb9196d05dad2eb04e4e51b019bf4136795c664b41605d8b7dd369e23db958abf30aa0547e4e91daecc49ad5691b539d735e476b19a9d31e376
P = a0720634e811d3b56e6635ef333e07e8bad7f90b402ac54612987b063a45be166428b79a182fd397bbbbbe0784ded18698432a5a92baabe466261fd4172067d8db19618835780c462312c5c0f22ac70776688aa5d1ec2ec51cfb87cca7e0d83fe5e1993868bf24ba94246bda831b52ce18ccc1fba875023a746fe9d60211dc2ca03940564339e6c1336a8b938cff07fa65e70675d7eec363888d32277e04408dc301d726d85fd402fd470210289ca6157579ce82a4318c9dbff644a4e7ae7bf5
G = 6ff1ac69dd73a168375e76ffdba83be33a80b43386055f8227145adb31c8acf10de4d4b91e73a6bba9b67e3e90d877cae8e54eafbbe976856c9b75cee49047f8a8731b6117aa94db7b93c5265a4fc611a3aa0ed19eebf7e173abf18ad3cb4c72204408de077ea5737a61300c2029400a8e7ec04537d4ff368eb4212bde5e75ec9d90d906a9b733cfe95930d97fa8e799775f0044ac3c45570a692035e437939ee01f91a5ab222f760d0d7cb1db082d8e84f11240699c0101904e014ddfabb372
Q = f24d8b3fe30c92264e42c73219aa8aa8425bf95b58fe0926deacfd093386122b
X = 1a51d6bde35c998c1eab52547a668344dcf77f842b6d1252f4a1f71b72669c12
H = 62d841a83a405ba9a29382677585800de759de38533871ba1c21f33b3b407f8a9bb0831d50cccd36972aa4e80ac5643336cd26392f7c2690107b5cb6a3dbf8297cb04fd9adcd8127a173dd09a95d746bce401d5f611f208e9491a71ddb0b3f21e94e4739b607d7960f17ad39882bfeed75977105c7d4e059d12e8f60cb55a78c24c1572f16dae385a1a6d8cc91002144b59af2834567302dd5b3e95b90098c66be07aaf264d8c1dd32bcf8757a25c6d48851c04b5e0ea950e641fb7be4a96063
Hash = 4d7cad7a2624b1bca215914dcd95c8f39f7ea69b4446374e9cd84992c7f20430
Sig = 6342921896ef24028d52249650b30155728892e6f9cd1f3b895b423e856d8a74b62ab052a1a5cd051afd68d5429d75320041f0d776fcfdc8b8c68dd1c7ab9ab1
P = ca526247a9f82737443ccd725a47fbe70ef1c39ebd610ea5c7613578a9641ff95bdb6be5743a4820f4566b428275b8f8ebcdd8fd6d466da75df6211219a8e3e442687fcafcdbd856d00c918ea6452e3819a9af47513b70aa94200d5eac8a6913dadbfd9d63ced4cdeb4a423a759563584e776282f8d9d9c3139f0ac2a980cea8af44930645165903201813f74b2001ea2a2b0a09b18524002e87cadea423c1dda5f307530166777c7a4396171cdf6304e4488217d90dddbae89f922f372839ad
G = 334a66b812a25fe3575036cd2e904a33dbd01af85e46759719f4872139050dea09668c9d715e49457b2eacb31314ef04e25da16715834e11aa4e77892df1bf5c78b6c7634ea3533c825f813f4fe13d2ed5df52431ecfdbdaf98153c4e714ee18c47cef914abf7b76abad02cd36fb0721bc968d3c51697bbf842d8f0444a91b489bbf5a3e0f76e6c44f1c93160e9905317fecf8177e722db14fd7ae1e1516a2e8fdd70e29207a25175ceecabd104995a2aa8f11d8c4b3a797003973a0557e1d0d
Q = 8d16cbdab1155553d0b204f13da3f1e9c97947e5439216c3fa5bf2975b5aadc1
X = 36a6d5d6b2d2b73b0ed0dbbfda311199a082479011c5a94820038d72838a5b30
H = 9444ab0fea4e4417f97bc02614df5ffdc18fb8f89d2ec62701b59c693d3b1a33de31a61366521e9e949fc1542027d902a7c885d1b88d39075c4e134e3c4e86ae15565fc0eec3faa2e7602fc84b98595a5b8199a01cc6bebc974d1438cdcf325496c4aa8bb76bf374bdf15ece02b45d33112fc4384b42bad53daf7717558e4935ac6ca038c7163df69d67a8f4e9e2e9bfa997d3989bab12fabbbd393d674caaaf9a6d9f64e2b4a897cf04c79436a2592ab907646eb4e5dbafe2af9c724db5b07a
Hash = c7a75a6069874af7d4e4ce58e8acf9be4e5789227804bae9338909568df75c36
Sig = 55d37cc2f7814a430290e5eb4020a00ce923cdbf8c880e6393a347a8515911c88c6c1429d3bc1c8ec7e88ddd0cb3ea703c89b913d4fc553090238f06712be324
P = c7e601222550cdf99750512218e295cbf583495784df356a72bcb850be904985e9800eeb82bef7cd0dfc53b016837cf529c475271349ad35f2376e3069d23001db3aa6c96cf99bb9ade4ba6cfe0929953baa361dbf900524fbeebb47d5ae0026fe2e5097d1f22d57a347db71f8b02aee523263eb5d278420a2bacea75c3df659
G = 2bad58efd750f7a3aa0d49b10b39cbffb17a20d197d23cacfd7011fe4a9322d4950d04f25e22d87d65667d86ad271362077d26fd466a313236815c3e4983a6b184a1616167dd5f389120fd1f283642ec288ad330b7bd2f4a6a344175e015802a970436a9553e5726f0b73bbfe9c4dde69640d6a599ae6f6796b7e8d201a0d1b6
Q = c5153d6a318358a145ba8389d144bb45b064b94d
X = a7bd1cf684aedab8e0d06e84a9dfafea7fc9d795
H = 5aa87351025843eaa7f766c1e0374559140f73761efa90ef17ce6840a1ab02a912005899bedeacf8b018b89f25a4b8e116486535ce28f3f6e66841e9526e6f5b10ecbc8c66702794e96f379ab746fc055ea883f196df52679bb45deea7876ab6ac0ef78ecd4c7b6fbea5bae3462ce7feec068ea2194539550dff83fd5dd98402
Hash = 6c2c15b68102747e86901845c83c622f272fedfb
Sig = 428da29589f18b9eda7ff627ac919092bd577a9b4a56eb7df1df004392cee6f568ffc1fb136eb24c
P = feae584ebe607945c29bab0e0edd35de7015d1344afd0f5a13d4bb448a3fcd9eea3a13fe83aecc2d41f9e0c0dbf59bdbaf9abf4b5b551f9e598b4b24901ce47ef350df4ebb2fae138e1978be849e916736a79e793c075609834a5de2d3d0063a4e700c05fbbf3b9a0070136d7ea44e3c14873ca790f9fc9b51714b7c3cb03567
G = e709f233a606775007060109918b368d5cb151d5713eb6f689f3cb88a730a9c038c26d721d88c3ff0121c2682106ecdbf437ea5664c47a3e3e44887df196df86519a504a8c68483e9d6d0331dbfc02f0b26dddd10260bf11c5ff35206571689854b942f58e96b17c0229f8e2c4a7bbe852e0260f3566eab77de9672088cd2279
Q = f502904da9aa680d55a6f3cc04064874711c5e67
X = 4d50b65a5ca664a3df67208835632fa9893a54e3
H = cb66cef191ed563c8824d45f9858504e796eccf5aa0b4af669823a136b1691e9476ef1fa0eceb14c2563168936b1f314ceb2ac7c753b45634742a45aadcdc5ffe3ff7c068b2ad57e33ad3dd78718d9a431efdcb4a66922c2a0ed98d9ce50b355cb1ff1784c3f4b8784322b15a2549091c5e6783c30d95eacef5759389c50c812
Hash = 5afd6af097175dff975ee92738901a31afad41e418b521e70f
Sig = 84c53c88300343de32c151c30988b2c26c868afff0fa50236c529a42e1211f64ab83809751595d1d
P = ba15af173c10632054eba274f564b6d08265279ce3a59f9ec2f48537bb612d6eabcff1c7f2c97ca038b381bf662043cb0846492ab2537d568b4a75b734f73f00df996b7b3aae7dbd38205bf37520a4a5906c7d300abc66a1a141cbc76d41e365a77406eedfb26a351ae487afb3a43d9c74be943e53b362d750761aebed242b0f
G = 03234e304389da633c315fae772d7d79acb7580ebe54703ad1d86f9169d92cf0ae6e8a78992110833a513c12a7cde088ffe5873743bbab28aeacfb8a4c32353730b5a1b524526fd95f8e8e8c6f2e24be48db56796d579d12e52ff7610f7307a3b27bc30a0f53eaca964923656d38a35eda04fe4d696625aee65a4ee5a33a630f
Q = 8f48f82b06184ab30e1c817b92ac7205c7798295
X = 427d24999999e5bf9708ecc9835b55fdd45bbe38
H = 047a559082eefeac71f684c233cb3d572fa8286a54eb48a4b33cc5b20e9cefbf44edef592651790527acc6957f6cab299f8046418e30dac36de498eeb5330a235ff9716916baa19e01d7efd6b446bd56666d1aa6863081b3e3552ba5e81df8e16e71cb15e8867844fbeed296ca274e28e8eac5a6eb4df955c34bb18cdaa1e67c
Hash = 5370b1a321be0ebce5ee26790e3430000eea5585
Sig = 3fe31f544be1cff8c2f35b13c30596d10a1445bc4361edc27420303a73e68472220f3a61cbaa62c2
P = fd41189025d4dad4a9f628da44e365ba6978ebe6fdcdccc2be60f2a1fd3ba243c5dfc15675f8ac131699746a1459e6c138c74939cde06238185d9fe428d92639e704335b5b7df3a38a05009470c3eb3db38c55a20d3e7e10b41cceb1fcb4a51c89ae6031c823c302e34a73dd7b4c272199a5f2878556672c68b7d5745e2e5837
G = 128b9f68fcd8af85660e8c9255f1dc5974e4f81d036a5abd64487f3f9d4a79c84871b9fc6d423ccf2732cd6837baa856b630a70167127ec2086487d99b28ef0161f4b7f2445440803ead0975772563956192e938aaf10c7cc7fb59283f8ff729d3de9885b5b57bf858fc97260cb0418b8df2590b2df51058b24ba5fc73bed5db
Q = f8d2c1e8deddcb2a0a39073401ff79f07fdae0a1
X = 380d120faa2223005ea220d38a340c603c1269e7
H = 7870d46afff887fcb10546a8f8c7250ee09206b49ed6ac745c5d001de29254cef548a732240a517f6aa32aa124d4de1b3623fffd8b03731ef9e226c5c48a136b2a5549cbb6427f14415158bd765a3960270ed49617dffc12e1a3dfa38a9e3d4acce3116d32f593f2af99d4d8c5d989304bdb35eff389536207e2cb611846b0df
Hash = fe578dd3303602e907091c994a19ab32d5c5a08455521623fd46713b188fe992
Sig = e1714b94692e92207488855bd870a5953f873cffdc5a42f70b48de66ea90eab92600c09476002b2d
P = 9cd5eadcf0e325980dbde762dcf1fd8a07f10952f6b203ef4578e42fe525363b43f1c176e4141def27bcc6dac9de680239bc87d09f0e2b8ebd83fa67483178d9d1ab528ee90c6b55203f5d811b1b8fbba859e64ca0da75616aee8594b8edc5a4854f9548abebadfefbaf11cbd7b1fe106458792d964b2f7b9fce681b80071687
G = 9b9ab34a13d9a04eee3b9cce04f7277fc42663c1c96cc089deeffb5588f4cd075e0bc9ed3e386bc79227156d93be4735aa04bda2fea53e5475753a1460bb63c5b7817190c02a26ec75dff594f499cfe363c03202074ff1b35cf8ffe4616a01d44228ca96ba5b0e2235e50bbeeadb420a962ef4e6aaccbe1ed2487a6542b1c25a
Q = a90f8cea77a2547b987403d0207a900806ba5871
X = 16b5936a546d671d452c9300fe748dd9bcdb6a78
H = 70ae90aa73344a5b7b81ce633006fef9804ad1b0284eca915e423c75dcc22498c502bcce654d8c97d3233cbacd0f1e1c405397065b5e65f4b2163674af2d6ab654393fc449061e2f12d0f56be5bbe41971032d99771eeec1b75e1e1a0f9407ee4581a82499e52f7b17eabae469728e5ba6c3757029513300e55144ab3a83fd47
Hash = 6a883c024c1e80e496561af1ed2c9316ff7b84edaccb8c1efcbf22a193578d0669c277d0411e06b4ee4cb6c47fe48e7d2595d661c16cdd06716ec06338bcc7e0
Sig = 0c5dee790e199993d7c41ea9a8a4806735126c8ea569bea1e8d32eccadcb3f6c31f7f4ce2d2abe37
P = fa9ec8aaa09aa5df3c6162b7fc326f61ec767fd5bcd563fce98117b32ecb75c3a3d325e6c386177d4c85a6326760aca00d4aadc4cc3b3612d2cdf19292de53a530b294d7cd2cccd1907101b550ee7dddd4ffc7a72281bf378f4489aef8ca9077
G = b9c861fff3772fb173428f87e924199349c576588bf2f33701d44a759857707fe0fc0b658951233e3ba1b9e8de8bfe993d2a14cad1e7d55ed5f06b4c424bf826f78b4efbdaf3a7f9156d7cacfa857b2b3794c860434525cb2f48da20c82b0583
Q = 991d3779b9e160256cdbde2b6f602b202a66212f
X = 59d40e562e0a63a5e2cca8543d4431ddcf8ff093
H = 8585b0ed6868988ff78644522bcaf010fa7be718e1a547263aff81951cc518ddbfc36ac1fb665bc6143c50e145cc1e410084bd1d365b8625f0b12c2174fbbe37c79a5ec7608ae90a6c2fcecf674386b677794a3bf59f82f28029d8bff763eba4
Hash = 56b0a58275137cd7107b3ab6740a656752c299c231fce6d4e14a0e154cfee825366d38ed0681808d3438c4526b2eabae1517e9e7bc5295099ffa1c4c23c9cf4c
Sig = 06d24d6cc65039fb9f1b9be49336eca41adb354b38c34ede7cc065aae0805b459633882f8c9186f0
P = beefde7b9d88140c56c20fd7637a0a9db6a8b9d28e1484187cfef5e96476a73235aeec4402f1144f16a553542167f0c80e8ed62fa19de24326469ed850106aaa831ebd700127d98fcc8ca604b8b0547eb70e24df0e4cf36310b9a747941a7bff
G = 55c9aa706acb0350869e12150c66a91fb90509dce5124492292d12180ef61624c4b0da6c71ac4c1e404e1ccb326f914889b8bc4d1e22d85cf6316ab77d3baffc32ce68c3d384e85673016452a69c4ce405df986580f28f178d1a0801052ae287
Q = eca819d1f485ce7784b003a84fdf43e6bd3d80d7
X = d24707c285b50becaf5b51107356b637d25c187e
H = 478759dba67172a349113711fc62a054941c9e9a4c8be68b2b1e4776c5f4f5f9c879ba7d031212e176e2c39e153ac62dd37685208a62cce65f8d5f96052709aab845f3e620e1ac0bb7e6de0fd0090b9849412e14872937446ff83c1f94ddf3dc
Hash = 0d385381224aeb318e2cb2100c7fa2b30f7d77c0
Sig = 830acb1e8c0c23691e2afe9be73409668123f29ca178a55c771ac0be57132982fddcfad5e43149ac
P = fcb2ccb2bf0999b883262877e2c00ce59dd9037d128cd559ce8fce8577591694014c4bd857bd41bb1dffdb6d0eccc99322da1b60afff8953220e8216f962440f
G = 76ab9bfa95c46b43f21c437f4529725194a05801c66106a9f2d799eb7bebe8dce7f947f469f4bc25788bc0802f80098044b45215a601ef781a7b57219147f00a
Q = ac2316a2d1260c282898e9e2723578669394e61b
X = a1d441318e5ad9bc6fcba54604f5439c0703c607
H = f3aba7053420cc21be923206387d654161b7801293c1f7347bcea85b8fa52f5c820cf3d89c84802e16f0ce6650648cf2f990f380fb3dfe1cb93e416a296f0edf
Hash = 0ee1ee37b8439e5601ace11edfe224a59f3391f6
Sig = 7029a56ac1ffa8dcedcb7a01e7e57997bed1eb402c477b03624cbdbe3e13a8f5e3c3d6137794ef6f
P = d1ee2cd2d93ca2446a30ef4b04349d0c1f55d2cd5fe98ed697c9c415c1949864ac530e019f88d1b39835a96eaba6668b829e5ae837f55d24813e91194899c0ab
G = b6d073ccca8c1dcde4d7f0c60b7104603c61aa75ce0ca7e510bb8f38d9784a4df3d66d3863cad607ba3e70551f41744d538b0d2e423d9e95f2af750515b96e3f
Q = c3dde50584ba725ac8a53d05f0716447a628f645
X = a9c247f2bc6f25829042bcf6c9bb23057ac555a7
H = 9a596e9ca98a3339be94072c9a50bacbda196669ea215891ce62526354c0004654c92fc8c9f6fdac142d8e6b93278290a90265e70fba8be3f56233697f00c682
Hash = f1924f53cde0fe9e9fedee9bdc88e0a34a46870eef43a75cdf00db0b54332aa0e76becb8ed7a5037daa79d15bb055897
Sig = 04cea71c55d492fa5a90742ffc7c6bc71b3d2d365d0761ff58aef1b89be0560748808e2fa2a62485
P = 16efd493f062e5e0f841ce0f8c2b8babad25b7d2b2bad370eff2caac242384340bb26a63d9c458530fcb8aa3508656ed133d8a7d2a04087cfce80fad9849a92151e827ca5bea31a9338fb78c75d78375b042e8d79b3f3ecb16b728a20fe9464f6ef745b4a7bf788908bfd96320df02a4b115c86e00ba6f4b5873398c328ee6b9a2fe8c2ffe64e5f0c88c27ac1ba765d328aab71ef6350fc4705baa568dca3e927a7d6a4c1410a92c209b89d586259a2e1b7ca474a57243098c88211c30616b7440db48fca906f050f9fb3776cbd86848a0148e8a6dea0668f8ec94235d0e8bd61e6283a7a8d7e8d5120c4b
G = 0af5ba95d5fcb812ff0c386a65424f7800d129f669e0649dd1cfc3da2fe1521a2a35802686bc70d2a00e00c04688db631ee4c048baf2e31772cf2d7d712fba3a97b5605bd3f6594df2f6e249094aa003ae3a86b336b64aca2503c53b74557daf4d37a0ea06310dc33bd2cce926de66d8c8112fcacf90204af6191bd504b6b2e513a4321237105f31dfbe7fe5e7e752b3b87b16abecf2f24c2cdad6af1188a6ff807890af07cb49216f745b0479b145ef17f6a014c0fd5eeb6c4efb0f3bfbf044d4c4cd458f1c94e80203b286e72a35e8d130699ba06b68cea2e369445180363ec932dbe03add50998476a6
Q = 027be01027a1e7fa6ab7521193899b17b3f2c352ea161424782f85d3f311
X = 0003206c6e2d4534ee61191dc3e2248b37984ffe3351e2a5eaed92d1d280
H = 14ef375c02f50b6091d0d2ebcd180a709278161613865b88db2a3daa5a1d8db1f20f63661224ee12f57a45ef3a11c1aad0a3e7b34e237430ef8b57ae82e640efc0a42bf652f9261cee083f89365bc993ea231ba3309de9df973ce2fabad97cb278aad26ca6ddc33f81396233d38a717e82a95562b6bbd2b8e0f3bda4217a3713223a4cd55e7e71675a4da855e579dc1150f9ef5e135a49ba885f2826e0a3a543550580af74a17f1ab3b1e4a1b9a55ff0269cd4dc59215ddccf723895f237bc455fc5d7d6c69b81c5152c51d584410ea1ab651356a580a169685c438af2ac2ef28d2cfa0c4d072007f0019f
Hash = 2a2f6881997c84f2ea4e458fdce7998fe827c287c78f106a627b81dcf849
Sig = 01c5705e04aafbf83ed669077b233e0eeb417cb6dd0bf3cc1a2e10c6b0eb007e69f62a1aee17caee5a93086380a720681153154b4eb2050729bbc488
P = 0d5b2996152fbadc935ddf9f801e07ea564f5802cbf91e7867b363642038095d973a428a22241e0e2b0416f353bb637405066b478c945133943da28039b459d8f82438e5f040d761677d8b05e241324ea3190dca495252379f
G = 09bd22028ea63b3dc8fbc5f95e2470020ac77c3149aa031b5c8f7c43b21c23c2d31710e706a12a9ade12d7a92acff951e64c03bc5174e80e87b45d4c98d5e473c204afbcdb366db6d261701efaebb401595bf9ef59adb2c877
Q = 0d81d729658b6f7da99162357fda8cc28ee02a8d044e6acebe51
X = 0cfd2d59260110b10b4023a786e822c92deccd36c4bc878c22e5
H = 087aa8821dc2a845ff3cf6a38a80bf78cd20b823115c853ab1e2736cbc78d66b976e27271243bf4916810da0007310c0559ed2f4ccc062d468dcf5aab49fe9bd05ed5bab93873864ea1ec99ef11544fff3b212b2e5d65df73b
Hash = 0d53bca6195eeaffd52f57491a31c0e83ebda084dac87a7a2d7e
Sig = 03a11be0282080ce6fa95e168b1693b17162f5456b893d7fb9ef016564e7ed8e643604f4c556dab5489457436c9f2e836834e241
P = 07c120180e185e2cd9e1e2bd774004fa4e2571cb828073ebc10bcb0708af92bee5f2df6c5637b1af14ade0f22795b9bdddd207538f0f7ab36f78cfadac0dd40af3317d80658cc0d9722fb7fac0a077226dcb22a54e02d3bd19
G = 073b260e545e6663ebf13f3996b039b07251a5b27eb91c00233d02633eb24d561b22a46757ac5949f8a928b2dc34d60ac0c5c134631edb6cb9026b31198496962d6050638bb90f952ad27f897739703a761726736aca195997
Q = 39b47ecff51b79de3d8e1380f9a7cd1c5973adb735ca711cb91a44a9d47fbf5017d9581346abcf
X = 28c2df178d5eb195be72f479693e0b7d8cd12a39b3e0f6125ad6caf0def6a8bc478243d1eda208
H = 01f0e0d288d470b90769538e4457c33802c4440a3062e8ada1d8d78a63aa92bd8732d2d092c0da9032557346f05a5b17f96c2611f4a239a57371a66cf85b54e9403e15c21444b7d79ce0fdc91ddcd6a41cedf5c9402c99b7c9
Hash = 91090f596527dc85a66712a6959cf51df63cdc200f08223d
Sig = 140b3ee31e52f9ca8bf226337796be45ff688365be4f190878681fdec0bb690a8886b26e0b008f0ee4dc225ddf483fe711550083d309b615bcc56307dbc8f6303e69fe29520e7f77e027e2da3586
P = 5a4a70d9f17c11b9e355421eeece27ea3fed0fe06a5c82057d435a13338ae31a57928b9e475343a7e4d365ecde6e606624a6f0e03764b70614b142ba225a827248660526a4e9fe221034208fe15a1ed3765c1016c05b9d12ba24f2eb2809a9dae7f837f104cc71b96de21bb0b3910ca08d69
G = 093ba61b67cc37b9a8c84317a13bb823ab9ad83df1e6527fcdb081aa826ad8acc31e2f57ca4e776701d44f1d933515af55570bc87821a66cb29dbaaade823e201113f9f5ee782e7bd606d4bafffc16fe32a67b64f9bf86db4885ccc4859b7599a550cf0128892ffdebacfc2518a59dcf6f5c
Q = c729082b1a73ab21c73e9d3ea1caa379ad
X = 65b05c1919e9e33309a8f9f3a071093428
H = 095bc5ee1d60e529a54962d5a39d34e33f92cb45cd405687ecf3a3a6d18cd7ddf091f518b50c3ef90aaadaa223cc089263a6dc6f347def54f6872c8a3bf803e9ba42e5092b8b200ca06186e49d7631f09f704d53a58a3430ee4e4bab8fbd82b4b1eaa0cc68da0abf9ba5081b6e23664551fd
Hash = e7b288c2c1966f8ddc3c22c6196c047e3c74f9be
Sig = c00b9ffe937bee2e03e6e2433dc5d88bfec2b2abeaaef3d027eab8082fe60574acfb
P = 01373743b6b20a46deb316bfde404478c1890e439e79f45ed09556431fead13fe23e601c87d3c7fc6212797311d2635d58a4bc9faf60fab7213964b9422001494a2a83fe830829cbaaf87b0f16a994c35a6cf90c0ea445a817614039efd89287c749c6bdf72403c47eaac19e5af031330633f0a63dd0fb6136a9
G = 001ff14dfb0150c62b62d9564e32679e02996580f5738458a3f23d5db769ebc8ef5c713925fbe03b0ab9f5e8912a82d66121da9b29a32ed44a218ebe784f5538bb76b0a6e85206c0b7214e788213607be9a322fa7fb39a4f07a9ff5629f2ed33f34a1073b35ac91d4e2718d5f9b1bc3aa5eadc151f4fea387fbb
Q = 517787f4ec50db1e039f8975f1497ff3c373af685e4087ed397309
X = 4bf63649708800f0d674a084e541f3e6af85be5bf6f45ae8299cc8
H = 00f9c894595425b12ea27d2672eab8f650e2fef8b453fe170770ea98eb27012dc97b14b3217764b5536787630948923dd1eabfa2b32acccee3a69e749debbed5d065b4e6ee4bd94e2fa3f4941a8d534b91de647ec4f6357d53be88fca6ce0a95976aae6f3b867f77afa86b5e9750db6e3f9311f964b6b192255b
Hash = aea6a336500125e6ff421e23cd2e20279ca50589361c3afef0507a84e10a37f269c3c49b4917ce8a0d2d0b05668acf14101d38ff5f9e79abd700f221596d4287
Sig = 426a7e7dba885ade09c82f83276ea0df3e003b8cb49e18fe63e9e90e38f28da62dbdf91836a6e61f767fd36e4f5621de0c4d8f8154e4
P = 05107a00c3cf99d366793d6c3a569f7f69cda17fbfbae87a90eb16f805108884219d66619fb30b75655ee4334c0ea7b4e4d31f384d55db14a599796ee233df23f6d728e419e74a345db005b44e5b339030d7f068090892137d5634d62c727e69b7df8982d703d8ca3aa7c20edc33334f7a7dcf4efa2fcb1469e46195b678e73cfba17268a29c7a46779f004f83a4b338f40200baa6f06a7296ff28c261e0519eff0627122867da0888b03b3cb3f4c07b7bcf8a6ff1ffd2d21f80f02aa97a746a317f09769d2738c4480d53845a5d57635d7e75c23bcf0be5d037721bb6a5c5b8db3e251f
G = 029e786cecd355a7c7552855841bea4cd06d9fdddec67c3f92ccca7c2641e073bdad9ed8fb0df104ab002e390fec66a51fefaa3a003c27f74f71290fe218f418a689b0ecbd9b0d7fa372667519c2eea416d8d8df709b7fc4210b29ee920dd98ece8e9d4d4af1513e56b547b76bc55e73c57fda37d167306d2cf0d86d96e7a13aaf21cba8670e1e5e465836866c918d554a85cf72ff7d129a8315fed3b4410ed22b6ed0237d60dd3b14fae2037210fe039e360d65c50577b6798ef7ebf9cdea357b3ba970c1d5357d10d488d4f059901b11ef2c101e36e8bbe4a071b3bfc59bbc35fa94df
Q = 8395769bc7f9bb337e50c6afb4e4bf45
X = 744773244bbc35df55485a73f2035d36
H = 00ca086907791e37bbc300ff3575044909e2df8737ba68bec114051763ce62a37cf34171c2c22d1237911892b6d628f4729d9ec9f89e9971bd38c1e01d2f7557434813397fbb68bcdd7f238c825e47be085f679ce9e302789cb2c955444db5ebf52bc853e7ce934d58ee62ccf3a4084db0e8424cee4c8982fa90b1bc1ae8db26fb3f7588f41c99714b48573b33cafb31bd221fa2a06432242ae4658055b536eafd2e8e95726c545c3d6c6c38a6fc016c16c58828ad99dee626af335e29669bf43f49d09fac2f976d3136cc207758c28bb78bed3f3d43551c4d8993e18c77a587e96b039a
Hash = 8756f1020c1e05e7b9f5e922c038e62e
Sig = 51051edee3c24bff7ff17804ff279d745712c9b354996a1cb62f2d05fb7a0c31
P = 6f12fe34def5e6b7d3b568068bd26612db927a2d6be3ec0134878f0c2e97c6bb3a7c2cbd025337cbde9cc05ed2afd2a20932cdb345c7a773076da35b99e7ea9dc605ae244b0cffe40809ea007a821cdb0dad38f791727b846d003817b3a0b9063b6476ed0a4406dc8ec0edd1fc72d0689c415d
G = 590316bec4856f43b8fec4d40d178eab61c78fee6fdbed02bacbf73b488e8b0385b815affc4a46160d5268b38c2b5206aa7668ec8fc691673c835541ad376bfdb349c3928a5da92963986fa69099c4e7b31ab99de4bf68b9c4d0f343506846db445a3a7f86d932d8c8ff63c50804b01287450c
Q = 800838d081cfdc56936d34623acbd4f7c7e577959f0ca3380c67beead52fd7825b
X = 68e4516f332f54ac41d9724dbe83463318211c9b22cb1d10d72ca63dd7cf2b12f3
H = 00ed03e7610c7d0f56b9120335b2bca503679ad1d79ff8c568a9e0f5e15685e68cc94b9d76c9f702f9699363e8f968abb21f45823628d8158dd92cd5fcff4ac03c53cda28d9b76be7dd66a1557a837cafbb3e08eae349c8a03651abbbddb21c7331252aa1220c10e32aa56fcc82ac134182d31
Hash = 3cd1ab4dfc4f96025a82381bb8d73dd0bcc01ac9804797eefe6402e0be66e07fcc
Sig = 5e5a8440dffd4279993708d9e083e4b944c7a448490a800d03f20d679de785db3d1977739c25bf0c7653bbe313e87fea02c59e0d4bdbdf1834f1616dcae26bef4f41
P = 435e4727316886f3d4f52cd65164a30af4e5ee0575920a2aaaf795c34d9446376cf62bc841afbcf20c6951ae488073055dbe0a226c0d4353d6adb36febf76e01fa73c6a7b37cb6176371cdcbf7da0c9086e1e58e07212a65817e31240ed483124d73f2bce97dc053b893a67c6f9bfe0c2e39bceaee4c40f69367138fcb5ef116859a3d
G = 33d8531ce6144350a86c0e67aef8282f3aad1f60122e6d61be7a046522f95a6506f007def87d5191fb625aca6f88ed71f00356d2d32bef7917c9629a61e9013158da76feccbc482590d4bf3a33e5501dce943cd0caf47bc4f02c779aaff016e2d281d95d62234d0eb48775d08ac24d917b4dedba5253ac1f3d3f1b64addd0dcd9f5c9a
Q = 04b45c12f64a7723824a4ac5654d0cf10a1b
X = 0054b5a41f498df7c470a89f1c00b997b293
H = 310c77a8c02cb611ab2c68cc0d28d931eb0c7c8987c4ce722f39df9eed046ed79660c89c12cfc593e42b897e65af389e0479376dff6d17ea399a2ffc3300f25af21dc1f07e0f8a7e5c0ee8a1afdf3aa6742c5acb269f02cb4a32caf0d46431e8a2ff3ab6b4c2fc59f6ff59b266661087ca60cab32daf453a2a20ca6b7277805274a5fa
Hash = d535a2e8539908ca99f913cea6093aa47636
Sig = 001009bcf413233c7af4fdf3734abf8f16c301bf663737d368817f89b7b55bb82150dfb5
P = 066bd8903e8c2e25ba7330c79a7a48c02bc3f5272930f645d7ee24be7ee8c45dbbd2ce4d3396dd070af939dcd121936b2b39d9a45e31f5adda4bc930ca87b2f63a2fe9eedfbd7f24dc7532228315367bcc34a426dc45bca8f9
G = 014a6798e89721dc80790f6fcf463dbd1f540f445916179a795ae6b8956d4c27b3add93039b1fd7471ccc3c1a63d98b52ad7f6357d7ba7e8b91874f3b0340691218c20901d60e0fed7a062ca4cf58ee019f9269bb108767555
Q = 068ba4db3422f3679320c9110c82da9fc23dc9d0a6d96972a97855d2e3542922786d3c0aabe5180af8ec1a9f6af3221e954e0f09ea7ca8c6da9f
X = 03f95880993f96f8e58b65b88e9abb4e811edbf145ede6bdd1d08661a1420ea32696aa97237911976d926c2d040eb6ab62b86e28503f5f845b80
H = 05738dff2f7e598909e7573b0b55fa828d3c1d2a545281fc80353d9f3caaefb13ebb203143c6b023a1232bf61802d4f3138663d7108af3e2783791d5fa6270ac9ad07073d1e111834a09bf39899924201ae3193718aa3dd556
Hash = bd6cb16b01e5cd2e23faec08eee88379031c654213e8e72a0cd4348a6ec5bd4af1650598d83a36cf7ed79df6a1a3968fbb100064a3269e8ac4de
Sig = 02f5a9adad76f7f0f0705b08916d8d5119769615562a0536af6476c07baa0c123ad24da8e1cb14361d440cd5e57e97106ee1d5b7e81e3504823205191ec05c61a5a42353761ace7a529d3c9a92648dae2d6a14fb7421a6b41c1fbbc72f9b3e9d96f7326a70d512011e07d10c7a04617b4cfef6fa
P = 8801cbf81a1b00ae99f14cf3c226c7e7c13a66fa4ef376e2b5efe566642f556c8b455f8746d1f6f03a8cb00595edfc8db223aa65c8bb9d9145844fd7e8783f24dc32c3
G = 64deee942f23f28af1d39eab6cd1d16d255c8707edba1cd17592436ede6bfa2283f2347445877fb767044d8a56cdfb57570d6905372f637091ad2346270cbf99beb1c3
Q = 2f103488e818abbddd9ab07c9d34b59c787c78ac6a1164ea97
X = 1c8d7b71a243d9e573783516f340e878112d6accb6c789cc77
H = 61c5cbf5e7c5d845f52b218eea39da3e9c3c901673c30e52d9cc7f756d95d53901e6c3949a7eadc2da19896f9d6fd7800a9fa27459b6a076bd82c59fe2ea2304f48b47
Hash = 9b913095ba0318d024142a1cf26b83cab01fc3cdd2508af9656ffd775f661175
Sig = 0a97aa9e29f917eae89572a561177c9388d853e0592da5a22e2a100eff2a13c4a27be7bd846ae85c2f7574b5cb260c1ab78e
P = 0efd7ad445b4ae230e04a03518537b33d7b02874b04ed35f372f0d319c9c540408ac3bb357a983c18e5f64dbfd4be420b8428ebc41bb200f1b99c39e66a0cf7fea775eebeb95240d532bd88918c6123b7f8a9568d8d933e87df5
G = 05390feaa3ddd781ef26df7c41c84aee9a953495b3f3bd2495af44e2f079f6c560a3479d0637443072099e4a46f9fe9230f9e79cab4b88ce0939280040d294f8c21cd252e7f90efe9866ddab20dcd465e91cddb0381316bca6ad
Q = 62f830018d31df4d0362bb58c9562c9ea9fba123
X = 57fcfddac38d014a59ec2e4e5241f777f906be2e
H = 0733046d18e8d5e67c39fed0e70f5f1117b20ba32c6532bdd39dd3bc6eeabca2017518a29504c81aaa6eedaa6268df891ba12a7b3e6bdd9722851323560d38732d7149f0e9e501bdf57b4b29a869ed6752d4433dd95203c681ed
Hash = a1842151ea15f89071508c34b73c98374a4f8447d0f99e0410549cf7e7a04b1e
Sig = 2f0f32c469527c14b61a9bc7438b002e32122ffd1e301b387fc3c7fcdb4419f8a6f1d6e1767c31b8
P = 0aab8a84418c6d39d42694aba28c4b9ca4bf39918b9d978a756ad20ba2b9326eb43f178ea09c7950403e4d2e449d8f04fefa0b9d11c5fb74732bdac23bcc3de65970e060e279a8d24125eb1d7e29c5a6a825af
G = 055c1a0982d7e2651a2766f59b8a3236a33690962a27d43f1a931b3b9bc6e85e7c9dddd851494d96c2a7d93f1ed4b544b392bc991157b68b9a20af06e3355bc012dd08b016412a48d365baab46fed8b89b6f0e
Q = 02ef6168935757cb00b88d32b373643f74dd15
X = 0051fef31ac5d8739587eaf749f7a68ccd2018
H = 06090041bde332d314bc9613112cc8d02b96a87dbcd38267af4cbbe1bb6836bc89dc8aac3ad591d7ab1afad72fe9e80fe7c3cde1c878a2361e784914630dee7048f05187098b57509ae4030298e29f792d7628
Hash = af466e65df0ec2fbff202092da3268cee5f95a7b4b6ff433c60ca5db293f762912ef6823ee55486fede6aee6334c3562
Sig = 003cafc9b1a9559e6379f089685dc0047db582018b0ff886a390065f51ebacb58d4bf80de949
P = 0b7494eaeede61fac9d16d13169f9c1f9ab7e193105501bb08f4a11668b4c43aac2f57948afe20d2beffa8055b1332f6449d3de94ecc735163e121f65521b532bec15aa14f9ac05ef016f1487e6fd300ae89
G = 0452108a3a11412f8ed343e10447b6f9611bfcd958d1f2e81032d40792fdf1b86fdee50a1c3f3abca566a9ea1cccdb6284044a49d872a2921235c0f59c31a83497fa9d3ea1c7a5f962ba247bbaba96c9a4a9
Q = 017e93e716b13d1ed6ead9c32d9cc7cef9083700f99d98dd939dd8c8d3
X = 00a2d8658cdb0ed29e72f6db80b4e87bd9f9f3d986166b335de1472576
H = 02a2795809b2db2b1e25809086c6270bd4e994d27e6f06831aa917852eaae0aef1b160aa43d3785d3c826e29efbf653c77c8cd4ddfaa86f7966292bda399a95fe45d90d3c6eb9b4032a9f3b9f3802da84ad4
Hash = e30d76b083137fb983bf8b5197aeba6fee1987641f2868df9cde7f39618bc81b
Sig = 00753077279b8837be92f00937e5d4fc1b33d7a6eac123fc9539e03e7a001321e4ae399b89e87fbccceb04221c56e385d687efea22eea01025ed
P = 3323f55f8bb8f98fc135f5f569cdd7f631cb5a3beef8b2d4b8d759c062e27440e892476f81875835008f6f1821c0d8fe81ffa89ce6745b18add58ae5c6394e337f99ea6a70aebbb037d96f1caec1174be7f852ad4ea3b4cd775131b88d4fcef68aafb6f9aaa3af51662129f0aafde3642510277f
G = 02dec62efa76b88ba6bb9f39fcc0faabb0fe0f26857eb2cf83a2efd8fb7092077ae547b5afed218c0ce0202e990e8bf66cc0f34b345b064ba8b00794cf37a70e5f2290f6e043655c3838a4498d219c12a2795c92e39446a282a58c878a72c0d6b6d6dd7a14ce423531ca1e2ffc04393c9d5b6f67
Q = 5ef0895b37039d4c01279667f64823354bda975c61ab39cfeca4f86fd4b4f3f9d9eb0f9d06c8f350103bd87788cd
X = 168b129421f6156d85bccd89f5d8ba36e8fcef351034a9db6a631b83f5d986c25e217d9f25446f28dedc4bdf2600
H = 0daa75091da3fa024f84c2d05e052e5a619bb72027245a1f5cb7a6f129ebf3b89d0e20a2995a248b9484257cf6d5ebd121be1e035f5e4a2a5d54c7a5541219f0ebf48fa8678ffdee36db858ac368eaabd949fcf8f6e8d2f857756d7647dce7c3f07ffac7db727d5895d0a9f6303a5a583666cc79
Hash = 11209f14c282386961ad320cb094ef76932d8db432ecc98076bdb71a801e47105652a9abe96fa8647b975a5ebf7744443e3f336d5187140e27bd1148f6b509df
Sig = 418621158c325b3661980883be601b8ecfe1bbcb2e5d0cb5cc745c2c38be367bd7a4442266a2b4b69b7ad97dbe273c864e50d8e013161c12e2184087b8f4890346efb02088de87a01be1f95325ffba24ddb8f03f4924ad3fcda5fc30
P = 57ab079f8239c4eb928881c8b78dc4096602459033d58f32760a11b8fd86d2d81eec3d4b89ca26a46073d514854e95e80e566f66dc3fd151225c0601efab404e35c4a952256a74d92d40fc3af430b8ec890a0176717f88ed44018b1d5090562e63f278399325a462ca722a2def91744fb3a1edef0d
G = 020464cf1c8fa3be1dfbab2ab4c85e7f12b3b4c5bc7ba4209a63734604fd4cdb48dcd91d62b508367493ed0b15dabd8c47b7f49f031ca48e2e18419af4c0aa371896ea7f7cf3047cf240e1bb1ae1724ab9be693a1a57082655a0ed337b2c2d25e7553fadcbf90220b04487c28c370a4fd680e7cd92
Q = 176c561b6590a5d8ce0fba8e24ee40fa1f7290c64b63c8ab46557de29589fe902d1bfc5a404c43fd36c2d3d1
X = 07c9d5792a0ec769bb693219c0bd9e1bff2b3f73fde6bb2ab97ff30eecad2a5765409da8b05b2d625a047404
H = 171526867b2c98b7074950e8e90399c5f4c2fca227b17822075660034c3a35222f4b3da1e75c9dd0ce7f503d28818188eea6333303418a43adc73d58a8b8413ac4267d96ffe164f1ac368b1dd57883c473c288b51d7a8730d42094733c9039cc2e1b0509c25131ac451bd3733dc8022bb7b3a9954a
Hash = 6ec5aa5cd3c0722efdfafe4cebf27845cab8f54a910e0180053b9f719e3f8db8a10b824d41b4ab4bd9a83264
Sig = 16fb955abee4ed93f92af9f65d86b64e2738814dd76a9947d9c2aa4d72f7979c45c1dd1b8c3a6df2feccca2014e2fa58eb9034c641bf45cb54a7e76673f0aa1a412cb54a7069b6988eab957dd72c00e47414a3bc2ba3cce3
P = 014bea4d171dacc1e0e9d75fb29136a09a68a5edb81a02325af4e3b4f7719ef15277a0b6afac8cce3ebf951b3159d7ec6eed3942a75f754256457f34d67ade809922587674539f5845655430a9b29dd1f096bd51f3a47e1ffe903c916b7d881124d3060ed50b015f54147dbd8292fe30cb17
G = 008f77e536e5610f317284aaabe917c854ba0b23be01532ea7be8afc5b4561e95b6d4ce1c569ca9a6a2daccc7a3e8b3eba4e4b556f2931a32a950bb88ea31c2e6762e660b7408c9eaca3e95be96b3d92a6c298efa94c606ddb18b1ef5546c81b0a3dbf7baa289e7d8e980c6066abebacc90f
Q = 6a83cf4793f1bf7eb5336f85658814b62b79
X = 3e00d8c5655fd41038554860f655801949ad
H = 00cb88cf5d7b367e3f2aa16e223f0f65a93fdb39667ac99572695cd3bbc9209f079577873f5d46766b91767f5f84934e4f2db05ca5d85c4920c9f2d985717bc61963b279af49d0cf932f8eb258f14e1fecc2a2bedcd92adf6ccfac7f8f377198f89b90d62fcb6246a0d753fbacc7c03253ae
Hash = de40ef243769bf43aca8c93332f8b2987232
Sig = 07e42bd5735aead8aa46ef74f72d637f0a315a88e9b940af6fce99c9d0191dfc16902d22
P = 02e79bcec4b52c7bbf81ec9e8bdc489c122cea751cd39dba1fed3427282b070253955617646935261fa3adbc8d23dd32a9d6b1ca5d7ff590328f8178ba34be7d07c1083893febe8016dd8274f7a8ce7c698739ce39db0b60ab348ea2b46071c544329ecf5c45c9c49d0ff38ba505d6bd0c51fff408c9c2d8e2cd454e9778c1529d63036c0d33245974498c393c0c0d9b93648ba8d468627ba1a3bf518f25140ffd8a7813df41b1d5e2ea542dc57a2453095c08f72412ff6f72ec7532e52159
G = 000e316965e35ff1474d41cfc465dda12dc0f96cf9ca36cc44501b5d082dd14e2abb484ac7c971a6052d43cb1fca4c5000debd02d4715780bb93ae619484e4f5f845c65e8a882c28e9e894ab1cb58217c35e372ef8be6d893e54c39ba6f8cec28be342cc059c7d5cdd6597e96e1e686ecf1a71439981ba4ce4bf6726de1080e5d185eee585e750ef1174fbad7e6dc3e82431d3bcd42db93e2787f1dff956145062daded04071024e23cf0ef8e13efef554f44b8ad81d0051e998424889619d
Q = 072b8afa5cfbdbc2a565fd1a35ce6960ca06124b2ecd41dcdc736d2f
X = 0394d133a23209833e9b5985e4f6fb394e16bc71a28cd6efe00653fb
H = 001a25289d0be569e698a71e3fe0fdd2f911b97e37e49c09ff3c4e621160d3470be371c086dd3cb996e0ba901451a277d08617f19cd0b3132ffad025cbd05ad84a0b9563156ccbdbf743b2a4b234229eaf2be3aa552b5f63f50e0b3a3a687972152c2922c5db652cddf82bfc1792f05b0191a0e0a6126ad88f9fce8d94c2fa9b5e939e07de1616c92e7eb54e5190e5f0de2fd6302d8bd4f411cc6c4b1004fbb5f0a0f6a1a3fc8740fea0e88d2dd18fe0c0cf3128b246e9bac06f2f21e4a3b8
Hash = e3aac29a85dea94a4afc114d5bc0669507ee320998214fb5439f4effbb7ecef5
Sig = 02e6606bc0db053cada8715a9d60488d78c1f594a0da7fb3abfff3c900deeb823bcc9b5fbf66b4252952050386d9b0fd24ab4f35d4e635f3
P = 05f9f821779267b5ad5a147147a999bb54c716b802e80ca29a2ef59d03d6cb278854f831961dd3ee342bdeb568a5943b9a5563bdd85a65ab5f21f4cfce56a886ac4c44ad359d8cabed21d7e61f814162981a1c301fa8dca368d3ce1f95338a55ebe4279b4d23fa6de5a8da177dfeb1e5ef4bd46eea72c363ad870f53d731597b9b2e1bda549ebb5cd09dacdee0f95fd2aec0077390bbb620e917f7f74749dea528c3415d2e7a12d7b4ec5bddd663f752b29cf50b20afd60d620bb4a88d5024222f2afe905eab7107b1573ea3e4d918ed3781cbccd7
G = 02c808cb95da965637ec5f0d5e807f42608094d1fef09beaa64932333e69ccd80a1cec02bcc0e75cd3546d773be6d132958c493f7ea318d3b252fe05ffd345069528242b26347dd017fa301944a364b1d6914dfd59540d914db60053790fac3e799cc46a2f1c447d79ec0ad8951a67ac928c6d127d397dd9b00d48d75a3b447a3eb16032ff2c30f556e655e7cf476b62182de1680ecf785350236e6822b332da651e5f99b26d8263b7d89cb6ba73fef74b14c966148be8a11d2dbfc8fd989db182f11aca74b785a8d70057d00d7e9bfd713966fe9e
Q = 02848d733fa4066a76476a87215b94eb857d
X = 025bf0465432252b6e4bb631428254d35d2f
H = 035cd25c706b3c7d29d89ab9f19ba40d23e5f948e6598cbebbe624f9d92b0d0101fd4c13a17b382709bfeb89a146045b5d5e46b3efb883a1eaa1d29394ed028a3872454a2791c877ea6b14f4f19a289f473fd769c4641c855a83a03bf7d4af540690b8d2c9437a1843a3fb9824e5477237db5eee3157bb2de23bd65d38ad6482bc250c15ce0a1782211f6f12ce212d24104367eb349dd041539c159ea5e3e090d765f56bbba6ae679f8a8a052e7c6739fd8abb32f4e3ff86650dc8d046b5a8e75f9345db1773c84d345610112606c4861f6c176653
Hash = f4d260983f8d8cc0282c1f7a29d48643841c
Sig = 0231869a25105febdb4d0c0d9f992480aac801433787ba5e18b27d004b7a89c59a5ed98c
P = 0bff809fe9b1575d5e94c03f9c175717076c60d502214e35a9e706bd07e1690cb080f0787c6a66b00b52ae722684c3f976a1f7d231a07bedaabccd8557247d765aa8482a191a90a05dd571b76c1d7ae5441e8bbe3d74919bacf2a547
G = 028358c5a823b6a2291c921b5c394c8a860de437ecdb02e9a9b7787467ea0d737c85e6d136a7294950d6bcf6203ef88a1fb3fd56335a2902b9bca5237ef6b62389c1f0733b74ed027d0603d6e1d62900e4d3dc17ffac84e451403df0
Q = ff7920d5dac80fe1d22638eee85a3df15327b8ec1d
X = e8637d5b41bc688337572e78a6dfe87ecfc4339770
H = 0b7167ebe8503b388a74417bfdc54560bb39ca2c64dfe3d1bf7ec7b27957999af7fac051d7b25673c0f648b59ee1292cc22a63b565fd1b1ac7d3808b03cab3d9e839410134684be6d37dd147252910ca969cb7ac7daf5264c3f96816
Hash = d9725011fc0768fb1c8d810b24ab969e22b2062539
Sig = 5532bdbb501dd45179ee0738ad9b95275348144cf3ee8e1615b801b078539441ccdc57b5b7aa0c1abbe4
P = 0255c1726dd8785ced84ff03970b48dd82abc6208e87c50ca4da4b3fd15609078b3437ff03df420d5b13a087f731859b1d7d38ca3a7746a20be8d8e1dd750f9bc38b15b34c8cb3dfde9ec53285b229d11fc5ddf680e0a333fd09847768b39567d748ded54cefa8a9d4096f17924a15b8ba1e17ca7a5d87df0244e67c8195bf0b2d08e1ffbc1395c4ba144b81934ba48d42aedd308950ed62a9f79fc40b005ce68814fa3db98685d787d3343cae5c9af26816baf74368bf1d5895f2717ee28ff1e5f64d4c3b3ab6893ee515d68b184c7dd92b3a09a3afc12b9348a1feeff6b6f90a5d5d240d9eac3817af584291f1
G = 008c1e1914b5e9aace131323237efcfd63baadd2182408b4cb108641c394e0d7b773ce413ea1a4f762f90897a2db3926c13aee6af535cebf6bdcae03408c4f174ed131b94f86a46482a60e630a1cfde97b5c3d8850b7fc92bc016591563fcdbdbc785a70d3c183f3bef8cbb9bed0a8ac8739e8b7f6c7836d1b562e33a625aa2e29a1ee3b104d03c665585462616482eb10765eef13c10866fc4d1b35fe6e47b41f0610bc6b883ffe84a129164ccee6e546560113f3e6f85af7471e37d513d88b8f0615c3f857b48b410885ef5f6f9086a7181bff9c26ec83090e03978fcc227eab1a608e5fd6992177b42c3b2588
Q = 024fdd617c772a8ff2b7847f80eb401d0dfc808231c3b5ed80ac190f56564c1c6a56c503f544fd9cb2538b240fd35f267951ce39d78687
X = 0212aaf17cca09325c7d1fd7f08d6f02015c062200d90c66d8d0321dca52757b7928153eecad6b70c9eef229cd6d27e409b9eede58feda
H = 0048105ab5669c272c3c6d136a5b77cd238db833dbc0ff894cdf37141d61f823daa0572bf7b1bf652f0381cf49411dcef35374ac5a4016cacc5db2ea0ddc3d93b09443b028459543836a373f3b39ad7d66a51fede8819dfb2a598f792896a47733f85284a22399772749a78e4298f9e5d8d26ac762a208fe8bef21ddcf48dd13fcd7074ae8066aa998e2677af7e724573845c7455d197300676d679bc0d64bb821489aafce98c268fc2ccca0172e51d594a4bb33ab34b98c0770ffe5a8a09ddc84068368d3cab6ae6b1d39742c5a09e5bbe3b37ed3c4fcd2bdfe0e9d7fd764410f5145839ea4992652429606b93a
Hash = 8a915641ff33179d6e606ba66cc235ed1ac4955241f60979584ef3199dfd5b33
Sig = 0047fee82779be479c15080361342759465a8c053c045e9e75a180bee530a466446abcbab0db34b8090a271525cd0a0efc22f80e96233c00413f4c91df4cb4fa94476eca9b486a29fbac140c5ccaeed9d62d336b95f7a4da8d6d65a990366422aa2ac1a26391d2c7095ed4150d7f
P = 51069681da91bc16b3fd2977ece93818bcb2d96a7ccc4f74b3a7e3128f724cae92b72c1ab5961bbb1223bfe63e0bdb72b1963ed6a7f3050bafbe643f555805cc270a38fb580a1f4819eb2f732f
G = 35c20fd5bb26832a9a4b5721c7a8465b7393f8f4be3f7d1ebf2733b1d6fd7a221d23b1dc3c2042cb5b23a8bd518955712594260e0d1dc91540e2fbc62bb199cc6e6586b891bdaa756f5d8daf2b
Q = f336913aa2c75892d29819d586b4ec7d247e1c4e523e3ac7c62f6f44aafa33
X = c1c3b56928598392bba31131536898431cd4f17e02e434c0186839b7462462
H = 1e04964249ae3d631600d7dcdd0fce7990d56fc1d7bca70a29851af65e9469f8d24a3a59501e6186531ff3e64db79161607c4b7c1430778e97c62b63ec7096f3e0fcb30bdf227316d9dd060fa2
Hash = cedf69170266ee7e4f0358d5cc50b897b65b0b1dd1af5c970a30163c14472b05
Sig = 34a722e11c888409b17be520c658e7f6e4eaa70a00ad26477b73fffc4160aa37efcf4dafea3640d9106152dc326c51e63db42efc40c40dfaec2e45b72764
P = 033b8e20c962888556706d734d9ec07970bac6ff720ba1cbbcdc0c4458db3fd1c0436a13c36b5ee7a85acca510369314d95926b0eea4bf4544137fc16766cf82d0a4c04130770e2d2e282643
G = 020c9ccb9814f56212702518c70a396654d6bcf952d23026ed7ab83917b422b188de7edd7b28acdb74d122149a23a30a6e4e653bb869192e0a9f5a0188033baf964b6e5b4553df4995e8160e
Q = 360fbe4bc4f56a745a491018480d90f25be6732fabef
X = 078b5f0cca99b0eedb109e37adb4cfc49df6785f600e
H = 00c08359fcad12cd7346146ab4311e68dbfcf1cb28a235f4cccce01dc9f1a9408c6902e25384d2cf6b4dccb2b5331f447789d1efc5d0532eca35daeb261565ea4a07a53cbbe66283e2b7711e
Hash = 2c8a4e708862f0299f657c1a51dea39551f018146ab5
Sig = 0c8ab0b03515253b49d59296b490d05e3e99d07558d3034ac132100cee7af9e94b52c3e764d9cdd509c777b0
P = 2dfacc8961d6a4780cf21b991dae6dd4823dd07c4c18d016accdf27c25154dbc4620d014eb677f1624cb0b0c55397a7bc76cfe068b8b67c6adc356a357c690da74a0e12ea5f52d7752d0fc053b74e08776c7b70f93c7ee847d
G = 0903f12c9fbb29b2a8f42248bbec22a8f54cae08fb5e5482b5538cb12d8e7519efc336e3cfe03a40020a1bd927d96f6ca653d11611183f5601c515726a5a10b0843b816404c17e039c03d3e63b9ed0c13d9c6c54e73eaad0b2
Q = 51165879c00f31b81c1a2ef0c2fdc36c38b75b0a8ffd6ad8b1f674a04d6ff669
X = 369b38169a7044afa27a6b8d813987c101cc4d6347a80f8caecd411dd4f95bc4
H = 284b18fa7f0d7478d32ccb82d712c2b2eecc3b699065f0d42d6e30d55cf895c29a31efb198cdc9f2384690df3def9f8c621d9efafabadfe484720622f20273aed5ff1bae47517bc58dc49c27c4e1b01724bf6555bbce4cd1fb
Hash = 59d10439f8aee7527fc6d2e7686d39d496e861fbdd8ea61b70e79134050c7ba2
Sig = 29a42e6ad74589550d1583e846c670d8be174c61e96d1749f4213e57463db7980190d5a47fe3dbf214752c1c3f8295ab0166e6e14a4f9cb43830322583a5909f
P = 0b9b05bc8b67db8bae8fa007ade938082a3eb1fda54afcd7528e7ea7d784b3732bd39b424cfae164cdba0a14a7df50b7fb88a86a069d0e3a691dc93f71e2d2049fcdf5460b1da0039d1ef499503e88371549b4287ed2049f32ed24d425bb0c3608f9e8c9f6cd4662f79623cc01193c3a3253acaf1acfe4a49cc97eb83f07f77ab6a7246b08c7247bf1244b9cd71e00e77caacd70f691893c2be1382b5330f3a146fc2b1025a49191b6f5cb81b97c1e354163212e7bc8a1182f61687cf321f3723d074f24923d5897a34615d817e00b2ddf580b76ef94834ca888187a54e51527adf5e5c40d
G = 0175075752a96f92de9367094f16840c5a927095e20d57c4556110335e2d23e3fe7e7130fc7878598653809942212cb7c94c58e8816354b259550de5508cbbab6853608ef45e2d8fa80d93e2ddfe4d4c61eb217bd7d59573f9d583cccde2c21d6618cf404798e4ee3fd9afe8bfd912a1a661f1c7d4e13cb6383bc3ab3de522003b6c158616fa31199b7110a77d8e356605d282c47c01e09ee7f3c4c50d64a0956427ceab1425bff6364c56699693733d45c74f2db28753cbc5deb53aa51b9d512f2ad5f502118d6ba2b6a50633db51d056cf29b3a8b1e29da1b4732caf577fc4714cecbb42
Q = 029aec0bd3507370b26326b77fb07153acc01af880e5c5e0b295d3b0cfb1a0b38d
X = 0121df984362be84ce62bbb9ddc05f4898ab7ebc6e15f53e9414f6fa638f1f0f80
H = 0021aba3dcf40d3b1b168941b36b45583ac88fb588122d1f18c0677ca411df7147cbd5ed240fb413074d3c6f04fb552918cf3d5c2d0b8e2497ee7d5b8faf3f1e872d8dec05134bf3e09ceeab806ab46ed8ef6e7ca6313e68834726ae80e5546af3201c1814f7cbc8cf6123b7cbce60b7509f9eee9c77d4d60ef45e829b72ebc37b07836a5cf78bbd419d364f3dfae1b6d82b203ca4f3bebc098ffe176a33270119b35be06632a854d0864ab26cad78ee8328a0c894119812b7817974e812ce5669255922e74b8c235d3a3a32573d1d92ad720649f9200230a002c16704667f8b8865e8fa20
Hash = 4f84e6465cbf4fca4e4c1f9d3c037dfb4a9cf0418a01420fc66645ac439a151d7e
Sig = 003bd2b46c6e690f2b08ed6c80345d205a7289cd38207c7f319abfb032b676642c01d500e59e2b82b01063794a28646e419fb69203272b3bb37d44c20a32ca45333a
P = 0350525f4d5e719a43c79649581c855507556b93ffd427b191d08de5a49c9aff45a929cd49ecbb12fda4ddb55c9fbf2bc32434fd0a8a1c57444632db3f0dd1ea025db8d2fc8806553ef943c478889ad0d2e929
G = 02fa25b434c237592ef9ca9fc12bc89d2d5ec1b412053d804d607d17b72914e8e68386525a47ae7f41cd7faf3da669f9efb163a4dea5ac01b078c989baa02c7bba073ee7e58da480639a8e3f2e509cf3ff7fd7
Q = 1ad6f4cfe6cd9777760335be5eae54211baebecb158de13068119fcbfff711d73ba14282f5fa587b
X = 05f9c773d83f2c3b2f6d3298256d51fa58788faf18ce2ba63af44c5646adb8b268025b1dd6437771
H = 00537186692c5e769d467b2cccf183f8bd3d71d1000922a68213b57a40f62c0f8b00b7c595b9db8b27d85620668dad4ef0376a9cc5c66ebf80c6997b7c527ed9d1dbd4c65f7e20340b2f31bda3a83f2e235486
Hash = 4b2d6eada3ecb3dd5f6d3c994fb8b349a7272c7c7f002c3cbfca4bcd2ddac80a33fd2e1ae9b100a0
Sig = 138b417009c0d8626b76a3ffe6f3a814fa83ac6f321219f9c8c4bf1a1b5ce5e0d810afe6a8a83fcf19a92bee0d38d8ba6b7748a1c1d8761e79f813aa9b5742eea8632b9bb965f7d8a0a1a1327fd4e6d3
P = bf5e8110a9ffae6b0adf8f4903cce3d036eb9bd78e5c430edd2fc58712d7353bb4cde8e3121be2d7dae1ec43723a4ef3a479553b93e44e189873df7f55a9a867bdb1a8f6c3d159abc67024ed053c8f9a2bd5c7f6978cc71d72ea82c178bf96e0297e5c018c811bb5befafd9442e06d
G = 9446e65c356386c28b1279507b2bad2e08cc073f336c25f9f2d606e7feb766b24d2db0e65c90b3f7d5f3da1309a074bd7f925c0362c36f1598a09e4f918945710f5806aa29ee0f309917adbf7556aefbdbb1f1ad9c67bdd2dcc8115a5bc6da043b726f03b3caa2dd99311cb3bb46d4
Q = 2f2af64a32a70a2588de2b3bb73a712d5c2706e5
X = 141205f92ae6799dfbd5f84dad563dc970359b61
H = 400ad88668f8a1ec3913819e1fa1a8c851123e390b546defb7c48a9c25ac6cd5b17ee17f54b33691f8a938d8522b1ad3ab72013a1a01b8d7c0cb90e9f4664be756dca40341dcb3049086b27cf9f52e8e46648b5871d6d795b4abd7a4aa536817ef7017858fe7a08f98d257b8bf927d
Hash = 77aaee7c19128eebbbec2ec805aca12c4438315fb0f9e415b21583964975ba96e444e1018fe08388afc5f66642193e07
Sig = 139c605b787e333e5fd51f39d82f4f50027cc158140f233035ebe1967e90a8c3248dce44ed09367d
P = 2fd1c3de7ae66dd03adf3f220712dd0ff85731bf1f6dc8145311d55d4872ffeda98759caec685a8309e9a1924623aeae00e9bb9d6abf940549caee59aead192f2c68f54bbf67e0f7812167a2c6f099f4f7abc0305315beb30ad04c90213fffbc9acbbff8143231b1b2611fb819f9d9f7a1d665749b26f927a9c3426a6ac05925
G = 26a255313a0605d866e59a93c657b8c42b50a901c7e4a0c3fbfdca19db01e16c302b970c733a4cae2a689e4a28a791864b17ee7ff22b38663c618389e6a6558c436dc8263e510b8390045cad40cfa103824ff63f24d3aa3b99d8540516957c607a82f10a88da7587e717d4efe7c59401e0b1f53306179e5e5f88e9e4fcd4324a
Q = 13bab5aa42b39d98707b4b4bbc3b28f63a01cb9a332c86942b
X = 10d101f3612839b6c37281d442815c03ee2d8426135d0ac395
H = 2e2d5df0ee6fe809796a304f3814db77fb0f520b394e195df63e406ebd1c62a0163063f50d4b8701f54d439f3f9aba75dd9ad02788f522a8584bddda081cfcb571c282e2146e5882c9deec2c224fb9f4a31ab27298cfce32e0f88e8fffe7ac1daa68ead06e522db3db90bbf4af6a7b93a5b36c2e01d2ba0211ec3c439195f58c
Hash = 25d78e235fc397ab9c33bd202d66934464955ea0
Sig = 1157e121eaebb52008c86603ea0ca1960b50422d011825824b11251d392153ff830848aa7f4eb98123cc98edcfbfd116f6dc
P = 019515aa13bce566edefb3f3c2cc1c212b2fa795fff5eef7c9b8ce34238519f296eb90e55d18c6bd49ccf9334aa115b419c8bb4e0b1915754342c8497c1d8b8d5b14047a461f32eb0fabe7ae6f7bc4ebfa176798dd6f1a9e2c79e4c6585056356ba4acf45f1a7455197508f589cbec7fe346fce2b38e998be7897a1ec3e0860a203090e6f2dd223e969bb5a49834d436dd9472b050140eeacad702199cfe9e09d409e5c5cbd27115eb56ba010529bf5a49f96210dd755f0df2a5ffd1ef185ad837384baea442e6c4b7fd0213f40c01afa5ddbf4207f6d464ddda7ed816e48bcc3c43
G = 0061389e28ac09138f5a61687cfa690624460f3b0dda30d3d43c6729b382f8aff70050ea450af0a8b78442ff55598779b0fbfeded9f443776af36adec277d672046f12dccd5999817a004264d1ad59711497b82ee730d81ff21ae590cb7d723854dde180001f726f46319d8e487d41ad2269c120d0d70473785bd153f436e8de8568c34420701cdfbb40336695ce1feac1ce4d833a6da089a72952ae1b03246308d494089e61dac4423f7c57f9643cb968186c26dfc13b8fbfc1de0b35a468f78f3c271a5222e531568049ae2f5c41ee31eb71c60554d70bb49aa73190f072754ca5
Q = 186719a1e9fa73a1068f6b2917247af1b211c5
X = 06dfbd1a6c817f64c37ee330c5295238b93919
H = 0060fac731b79029722860d9e5d4343da9805f40e3b52cd80c1ef41f531008ede14730c5173e595d9ae433d4a0f62077ecc83bcc7524b134d52fa23a01940e2f66f9a1b42fba0788d6fd43ece61b4fc3b93d3ee6cf8241bf32b7340dadf8d41a20f0d337e87af8ad1f9834aebf628508a310feb31ac5bfdd1cb6657851543e95e9bc1f1cf270dea869a2f5e9a2e61280baf5212c114d5a68fc5343849809b7ccb64d75f50d54a7886ff3ce7c6c1b42fdff09d3410ddea4bd5ad43d3b1ca775ebf3d9eb0dd4c3ba2b050569525fd80786cfe9409fc57cecec2821b9bb959ec0ad062c
Hash = 28b2153077f8528d2235e0d79f0004fb3e0168
Sig = 14341bc1003290d2c747778d994371d7359de30b3ea52c0347f0af83467bebdb9ea575f6f772
P = 016a039bc69840c48bf0da8c71fa9691bab5ad154b060c5431c37c1d47aefd8199cca989fde0ea9764fca6ca263f47ccb068a8ac57cbf9d763828ceeb5f514f37bb75ac0ba6e04113808268d80c04cea496499d047b00cb3e67c30e10b248e61076b0c396dee60d79cd5c1a7ca0dcd6ed7a6c5d9e51e1dee58ff1f1d50a69cde0e5f
G = 0090ada8fc8f4bbf955b5b5160f1a06cfc1dd3af2baafbdc037468fa527ad86fb510b4d76c6deaef59ba45e6c4b14a986c4afd46fd891b999f71c29a185b0864faaa95e38fc9b4a4aa37838657204bad9ace39ed7e95dfb489814a274e03391854d31f5db7b9a3301d7014b24cc463448f877bbea89915dc32b494a6f76bcf42c52c
Q = 0118ed834ca47378ed2c75eeab43cc3cf3
X = 000a8d276cbea24c7c3f6b16586588d26f
H = 00cc6bd726f24718c710f144b433a17be35f55c99bb05bc8b46fe8414ae5b28c438562747b84824c9ee7fb52aacc50a3181cf48fa61329710d900d790399aa7333a3b8541faeb596a2deb3872120f4e1c98b0916650b934a9c3a119c2a7f9a214fc12e8a0a41718a47d28f26707435222107e6d6c2ed93f50ca58b95332a258e4f4c
Hash = 062662f9eef0cfb53618960362da803f2a
Sig = 009cb913040a1daeaa43a5698f469dd8d6007dcee173c18317d71e71b947c4e4ae93
P = 1d7145f10e3c14a12e96a1ba94db377880fe7333f06b1543cc19bebe7758584a3dff1809b3b6ba1f8d107a5391f505510afd8b531c0b8086417f7cf41e12816b5b0a1b0e681d6bb2fed72a2deadb8cf5d1720a30ad084e22bbaef4c734fb644db34a2939293d
G = 19ef718f3bb76983f8466a92aaac5ba471b93248e484828435a57b8c64eab0ed89d05215419cf0cbcf9caa2d254ff46cc7bab44aa93964183e8abd8766d55f8d3cc7f502bea8e92d5ef314ba0bd329890e2694634636c1a2c55651bd4efb6ddd111e37c825c4
Q = 0627574ae6a5556b97c3c4db1496ab607135223c7fa3f607
X = 0573095c6c98a9614cd502f0c14f7eceff8b29a049e052be
H = 0f29c1625608b4f1728abe3d1f08ac8725ed06b07e8ec25b5cd23cf9542ec7fa50f26e0eea041dbb44dd0896882558089aa858a7900bd0794795023f6606bc65e90e4b496b110a45f9d295766cd21973d58345be499447e94a79a1f678d1f491f0728acb4cc8
Hash = 258c8b6dad1120fa9c2565865453dbd1b9fc45f0
Sig = 027a0faf8f5af5e5e452d31a1102c5591377d28bdd39e6880247af9f314ce104894dfd1473a03f1a8905b13625115676
P = 316aea5e6409a08ef1ba8c7917c5f92ed7ce94e7bcb37a661935a3e29623538b871a2294e010c95d7a76cfd551e8cca7cb03dd7bee98625847a6f781bd4206dc627c377878e8e3edb9205df9e4c459306847078941d2c4d07b6542549f92122ef3662d73325222b4f0fd5b2ef533388a85
G = 2f15010819b72de24e52b42f4afea0f2497d711e129d423abc3e8994c553f1c42ee44f6968c7b53b0dec17750509fc80d464f5263cdeb085bfe78f2ea07b8b8fde565582335708a8eb94093582ab61e5fd602978f602263e8e27db4aae567c8439c73d088c677991c2cbafbbcffaf86a66
Q = 2963018a3db86fdbffdf7040c36ddc16cba4d8157df5494da9be45fdfa63bdd533
X = 243d8c16d1b1ae4fd7ed03b02896a2e775321438fd73f99a86cb01d0aa86f03d6d
H = 0569573e08be9c6d74372d97f870567eafbd613ebbdea4b82f41618265098b0572871bdd44fbf2959e1b4f9131e98911af844f6123b6a2598d327559027aa802069fb327de3e28eca1617c6ca60f92779d19115ec9f7576454b32de7113f46f6e54b3fcb97987c0986a12cba67ae71d65d
Hash = 9178381c6ffc45d36b92f44512e2d733bc1af45ecb3b4b5af4645f42b36a4269
Sig = 1dc79406561309475366c88332fb56aa40c8fb57ce006308dca7500860b5c2220d109ea33946f0e8cf2e10eb2f26fd4e6787c9bb7bbb02509eb0e49688918b7508b5
rnd = 1

Просмотреть файл

@ -28,6 +28,8 @@ set(SOURCES
testMontgomery.cpp
testRsaSign.cpp
testRsaEnc.cpp
testDh.cpp
testDsa.cpp
testScsTable.cpp
testScsTools.cpp
testIEEE802_11SaeCustom.cpp

Просмотреть файл

@ -2577,6 +2577,722 @@ RsaEncImp<ImpCng, AlgRsaEncOaep>::decrypt(
}
//================================================
// Diffie Hellman
template<>
VOID
algImpKeyPerfFunction<ImpCng, AlgDh>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize )
{
PCDLGROUP_TESTBLOB pGroupBlob;
NTSTATUS ntStatus;
BCRYPT_KEY_HANDLE hKey1, hKey2;
BCRYPT_DH_PARAMETER_HEADER * pParams;
UNREFERENCED_PARAMETER( buf3 );
pGroupBlob = dlgroupForSize( 8*keySize );
CHECK( pGroupBlob != NULL, "Could not find DH group of right size" );
CHECK( pGroupBlob->cbPrimeP == keySize, "?" );
ntStatus = BCryptGenerateKeyPair( BCRYPT_DH_ALG_HANDLE,
&hKey1,
8 * (ULONG) keySize,
0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed to generate DH key object" );
ntStatus = BCryptGenerateKeyPair( BCRYPT_DH_ALG_HANDLE,
&hKey2,
8 * (ULONG) keySize,
0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed to generate DH key object" );
// Set up the BCRYPT_DH_PARAMETER_HEADER in buf2
pParams = (BCRYPT_DH_PARAMETER_HEADER *) buf2;
pParams->cbLength = sizeof( BCRYPT_DH_PARAMETER_HEADER) + 2 * (UINT32)keySize;
pParams->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC;
pParams->cbKeyLength = (UINT32)keySize;
memcpy( (PBYTE)(pParams + 1), &pGroupBlob->abPrimeP, keySize );
memcpy( (PBYTE)(pParams + 1) + keySize, &pGroupBlob->abGenG, keySize );
ntStatus = BCryptSetProperty( hKey1,
BCRYPT_DH_PARAMETERS,
buf2, sizeof( *pParams ) + 2 * (ULONG)keySize,
0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed to set DH group parameters" );
ntStatus = BCryptSetProperty( hKey2,
BCRYPT_DH_PARAMETERS,
buf2, sizeof( *pParams ) + 2 * (ULONG)keySize,
0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed to set DH group parameters" );
ntStatus = BCryptFinalizeKeyPair( hKey1, 0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed to set finalize DH key" );
ntStatus = BCryptFinalizeKeyPair( hKey2, 0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed to set finalize DH key" );
((BCRYPT_KEY_HANDLE *)buf1)[0] = hKey1;
((BCRYPT_KEY_HANDLE *)buf1)[1] = hKey2;
}
template<>
VOID
algImpCleanPerfFunction<ImpCng, AlgDh>( PBYTE buf1, PBYTE buf2, PBYTE buf3 )
{
NTSTATUS ntStatus;
UNREFERENCED_PARAMETER( buf2 );
UNREFERENCED_PARAMETER( buf3 );
ntStatus = BCryptDestroyKey( ((BCRYPT_KEY_HANDLE *)buf1)[0] );
CHECK( NT_SUCCESS( ntStatus ), "?" );
ntStatus = BCryptDestroyKey( ((BCRYPT_KEY_HANDLE *)buf1)[1] );
CHECK( NT_SUCCESS( ntStatus ), "?" );
}
template<>
VOID
algImpDataPerfFunction< ImpCng, AlgDh>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
{
PCDLGROUP_TESTBLOB pGroupBlob;
NTSTATUS ntStatus;
BCRYPT_KEY_HANDLE hKey;
ULONG cbResult;
BCRYPT_DH_PARAMETER_HEADER * pParams;
UNREFERENCED_PARAMETER( buf1 );
UNREFERENCED_PARAMETER( buf3 );
pGroupBlob = dlgroupForSize( 8* dataSize );
CHECK( pGroupBlob != NULL, "Could not find DH group of right size" );
CHECK( pGroupBlob->cbPrimeP == dataSize, "?" );
ntStatus = BCryptGenerateKeyPair( BCRYPT_DH_ALG_HANDLE,
&hKey,
8 * (ULONG) dataSize,
0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed to generate DH key object" );
// Set up the BCRYPT_DH_PARAMETER_HEADER in buf2
pParams = (BCRYPT_DH_PARAMETER_HEADER *) buf2;
pParams->cbLength = sizeof( BCRYPT_DH_PARAMETER_HEADER) + 2 * (UINT32)dataSize;
pParams->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC;
pParams->cbKeyLength = (UINT32)dataSize;
memcpy( (PBYTE)(pParams + 1), &pGroupBlob->abPrimeP, dataSize );
memcpy( (PBYTE)(pParams + 1) + dataSize, &pGroupBlob->abGenG, dataSize );
ntStatus = BCryptSetProperty( hKey,
BCRYPT_DH_PARAMETERS,
buf2, sizeof( *pParams ) + 2 * (ULONG)dataSize,
0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed to set DH group parameters" );
ntStatus = BCryptFinalizeKeyPair( hKey, 0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed to set finalize DH key" );
ntStatus = BCryptExportKey( hKey,
NULL,
BCRYPT_DH_PUBLIC_BLOB,
buf2,
10 * (ULONG)dataSize,
&cbResult,
0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed to set finalize DH key" );
}
template<>
VOID
algImpDecryptPerfFunction< ImpCng, AlgDh>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
{
BCRYPT_SECRET_HANDLE hSecret;
NTSTATUS ntStatus;
ULONG cbResult;
UNREFERENCED_PARAMETER( buf3 );
ntStatus = BCryptSecretAgreement( ((BCRYPT_KEY_HANDLE *)buf1)[0],
((BCRYPT_KEY_HANDLE *)buf1)[1],
&hSecret,
0 );
CHECK( NT_SUCCESS( ntStatus ), "?" );
ntStatus = BCryptDeriveKey( hSecret,
BCRYPT_KDF_RAW_SECRET, // This exists from BLUE and above
NULL,
buf2,
(ULONG)dataSize,
&cbResult,
0 );
CHECK( NT_SUCCESS( ntStatus ), "?" );
CHECK( cbResult == dataSize, "Wrong result size" );
ntStatus = BCryptDestroySecret( hSecret );
CHECK( NT_SUCCESS( ntStatus ), "?" );
}
template<>
DhImp<ImpCng, AlgDh>::DhImp()
{
m_perfDataFunction = &algImpDataPerfFunction <ImpCng, AlgDh>;
m_perfDecryptFunction = &algImpDecryptPerfFunction< ImpCng, AlgDh>;
m_perfKeyFunction = &algImpKeyPerfFunction <ImpCng, AlgDh>;
m_perfCleanFunction = &algImpCleanPerfFunction<ImpCng, AlgDh>;
state.hKey = NULL;
}
template<>
DhImp<ImpCng, AlgDh>::~DhImp()
{
if( state.hKey != NULL )
{
CHECK( NT_SUCCESS( BCryptDestroyKey( state.hKey ) ), "?" );
state.hKey = NULL;
}
}
template<>
NTSTATUS
DhImp<ImpCng, AlgDh>::setKey( PCDLKEY_TESTBLOB pcKeyBlob )
{
NTSTATUS ntStatus = STATUS_SUCCESS;
BYTE blobBuf[sizeof( BCRYPT_DH_KEY_BLOB) + 4 * DLKEY_MAXKEYSIZE];
BCRYPT_DH_KEY_BLOB * pBlob = (BCRYPT_DH_KEY_BLOB *) blobBuf;
PBYTE p;
UINT32 cbP;
if( state.hKey != NULL )
{
CHECK( NT_SUCCESS( BCryptDestroyKey( state.hKey )), "?" );
state.hKey = NULL;
}
if( pcKeyBlob == NULL )
{
goto cleanup;
}
cbP = pcKeyBlob->pGroup->cbPrimeP;
pBlob->dwMagic = BCRYPT_DH_PRIVATE_MAGIC;
pBlob->cbKey = cbP;
p = (PBYTE) (pBlob + 1);
memcpy( p, pcKeyBlob->pGroup->abPrimeP, cbP );
p += cbP;
memcpy( p, pcKeyBlob->pGroup->abGenG, cbP );
p += cbP;
memcpy( p, pcKeyBlob->abPubKey, cbP );
p += cbP;
SymCryptWipe( p, cbP );
memcpy( p + cbP - pcKeyBlob->cbPrivKey, pcKeyBlob->abPrivKey, pcKeyBlob->cbPrivKey );
p += cbP;
ntStatus = BCryptImportKeyPair( BCRYPT_DH_ALG_HANDLE,
NULL,
BCRYPT_DH_PRIVATE_BLOB,
&state.hKey,
blobBuf,
(UINT32)(p - blobBuf),
0 );
CHECK( NT_SUCCESS( ntStatus ), "?" );
cleanup:
return ntStatus;
}
template<>
NTSTATUS
DhImp<ImpCng,AlgDh>::sharedSecret(
_In_ PCDLKEY_TESTBLOB pcPubkey, // Must be on same group object
_Out_writes_( cbSecret ) PBYTE pbSecret,
SIZE_T cbSecret )
{
NTSTATUS ntStatus = STATUS_SUCCESS;
BYTE blobBuf[sizeof( BCRYPT_DH_KEY_BLOB) + 4 * DLKEY_MAXKEYSIZE];
BCRYPT_DH_KEY_BLOB * pBlob = (BCRYPT_DH_KEY_BLOB *) blobBuf;
PBYTE p;
UINT32 cbP;
BCRYPT_KEY_HANDLE hKey;
BCRYPT_SECRET_HANDLE hSecret;
ULONG cbResult;
cbP = pcPubkey->pGroup->cbPrimeP;
pBlob->dwMagic = BCRYPT_DH_PUBLIC_MAGIC;
pBlob->cbKey = cbP;
p = (PBYTE) (pBlob + 1);
memcpy( p, pcPubkey->pGroup->abPrimeP, cbP );
p += cbP;
memcpy( p, pcPubkey->pGroup->abGenG, cbP );
p += cbP;
memcpy( p, pcPubkey->abPubKey, cbP );
p += cbP;
ntStatus = BCryptImportKeyPair( BCRYPT_DH_ALG_HANDLE,
NULL,
BCRYPT_DH_PUBLIC_BLOB,
&hKey,
blobBuf,
(UINT32)(p - blobBuf),
0 );
CHECK( NT_SUCCESS( ntStatus ), "?" );
ntStatus = BCryptSecretAgreement( state.hKey,
hKey,
&hSecret,
0 );
CHECK4( NT_SUCCESS( ntStatus ), "Error during secret agreement %08x %08x", state.hKey, ntStatus );
ntStatus = BCryptDeriveKey( hSecret,
BCRYPT_KDF_RAW_SECRET, // This exists from BLUE and above
NULL,
blobBuf,
(ULONG) cbSecret,
&cbResult,
0 );
CHECK( ntStatus == STATUS_SUCCESS, "BCryptDeriveKey failed." );
CHECK( cbResult == cbSecret, "BCryptDeriveKey output wrong size");
ReverseMemCopy( pbSecret, blobBuf, cbSecret );
ntStatus = BCryptDestroySecret( hSecret );
CHECK( NT_SUCCESS( ntStatus ), "?" );
ntStatus = BCryptDestroyKey( hKey );
CHECK( NT_SUCCESS( ntStatus ), "?" );
return STATUS_SUCCESS;
}
// DSA start
BCRYPT_KEY_HANDLE
DsaKeyBlobToHandle( PCDLKEY_TESTBLOB pcKeyBlob, BYTE * pbTmp )
{
// Convert a test key blob to a CNG handle, or NULL
PCDLGROUP_TESTBLOB pGroupBlob = pcKeyBlob->pGroup;
UINT32 cbP = pGroupBlob->cbPrimeP;
PBYTE pNext;
BCRYPT_KEY_HANDLE hKey = NULL;
SIZE_T blobSize = 0;
BOOL predictSuccess;
NTSTATUS ntStatus;
// DSA key import is a bit weird due to the way the API grew over time.
// There are two blob formats, one for keys <= 1024 bits ane one is for keys > 1024 bits.
// There are also other restriction
// - bitsize of the key must be a multiple of 64 between 512 and 3072.
// - group size must be 160 bits for keys <= 1024 bits, and 256 bits for keys > 1024 bits
predictSuccess = (cbP % 8) == 0;
predictSuccess &= cbP >= 512 / 8; // Min key size for CNG
predictSuccess &= cbP <= 3072 / 8; // Max key size for CNG
if( cbP <= 1024/8 )
{
// BCRYPT_DSA_KEY_BLOB for a group with size cbKey bytes is followed by
// - Group Modulus P, cbKey bytes long
// - Group Generator G, cbKey bytes long
// - Public key H, cbKey bytes long
// - private key X, optional, 20 bytes long
if( pGroupBlob->cbPrimeQ != 20 )
{
// Wrong group size for CNG, we can't deal with this key
goto cleanup;
}
BCRYPT_DSA_KEY_BLOB * pHeader = (BCRYPT_DSA_KEY_BLOB *) pbTmp;
pNext = (PBYTE) (pHeader + 1);
// Set the header fields.
pHeader->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC;
pHeader->cbKey = cbP;
SymCryptWipe( &pHeader->Count, 4 );
SymCryptWipe( &pHeader->Seed, 20 ); // We don't have a seed, use 0 and don't ask for a key validation
memcpy( pHeader->q, pGroupBlob->abPrimeQ, 20 ); // Prime P is always 20 bytes
memcpy( pNext, pGroupBlob->abPrimeP, cbP );
pNext += cbP;
memcpy( pNext, pGroupBlob->abGenG, cbP );
pNext += cbP;
memcpy( pNext, pcKeyBlob->abPubKey, cbP );
pNext += cbP;
memcpy( pNext, pcKeyBlob->abPrivKey, 20 ); // Private key is always 160 bits for this blob type
pNext += 20;
blobSize = pNext - pbTmp;
} else {
// BCRYPT_DSA_KEY_BLOB_V2 requires that
//
if( pGroupBlob->cbPrimeQ != 32 )
{
// Wrong size for CNG, can't deal with this key
goto cleanup;
}
const UINT32 cbQ = 32;
BCRYPT_DSA_KEY_BLOB_V2 * pHeader = (BCRYPT_DSA_KEY_BLOB_V2 *) pbTmp;
pNext = (PBYTE) (pHeader + 1);
pHeader->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC_V2;
pHeader->cbKey = cbP;
pHeader->hashAlgorithm = DSA_HASH_ALGORITHM_SHA256;
pHeader->standardVersion = DSA_FIPS186_3;
pHeader->cbSeedLength = cbQ;
pHeader->cbGroupSize = cbQ;
SymCryptWipe( pHeader->Count, 4 );
SymCryptWipe( pNext, cbQ ); // Seed
pNext += cbQ;
memcpy( pNext, pGroupBlob->abPrimeQ, cbQ );
pNext += cbQ;
memcpy( pNext, pGroupBlob->abPrimeP, cbP );
pNext += cbP;
memcpy( pNext, pGroupBlob->abGenG, cbP );
pNext += cbP;
memcpy( pNext, pcKeyBlob->abPubKey, cbP );
pNext += cbP;
memcpy( pNext, pcKeyBlob->abPrivKey, cbQ );
pNext += cbQ;
blobSize = pNext - pbTmp;
}
ntStatus = BCryptImportKeyPair( BCRYPT_DSA_ALG_HANDLE,
NULL,
BCRYPT_DSA_PRIVATE_BLOB,
&hKey,
pbTmp, (UINT32) blobSize,
BCRYPT_NO_KEY_VALIDATION );
CHECK( NT_SUCCESS( ntStatus ) == predictSuccess, "Unexpected BCryptImportKeyPair(DSA) result" );
cleanup:
return hKey;
}
template<>
VOID
algImpKeyPerfFunction<ImpCng, AlgDsa>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize )
{
NTSTATUS ntStatus;
BCRYPT_KEY_HANDLE hKey;
UNREFERENCED_PARAMETER( buf2 );
UNREFERENCED_PARAMETER( buf3 );
// Future: it would be better to use a DL group and/or key that is already generated, but
// this is simpler
ntStatus = BCryptGenerateKeyPair( BCRYPT_DSA_ALG_HANDLE, &hKey, (UINT32)keySize * 8, 0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed BCryptGenerateKeyPair for DSA" );
ntStatus = BCryptFinalizeKeyPair( hKey, 0 );
CHECK( NT_SUCCESS( ntStatus ), "Failed BCryptFinalizeKeyPair for DSA" );
*(BCRYPT_KEY_HANDLE *)buf1 = hKey;
}
template<>
VOID
algImpCleanPerfFunction<ImpCng, AlgDsa>( PBYTE buf1, PBYTE buf2, PBYTE buf3 )
{
NTSTATUS ntStatus;
UNREFERENCED_PARAMETER( buf2 );
UNREFERENCED_PARAMETER( buf3 );
ntStatus = BCryptDestroyKey( ((BCRYPT_KEY_HANDLE *)buf1)[0] );
CHECK( NT_SUCCESS( ntStatus ), "?" );
}
template<>
VOID
algImpDataPerfFunction< ImpCng, AlgDsa>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
{
NTSTATUS ntStatus;
UINT32 groupSize = dataSize <= 1024/8 ? 20 : 32;
ULONG cbResult;
ntStatus = BCryptSignHash( *(BCRYPT_KEY_HANDLE *) buf1,
NULL,
buf2, groupSize,
buf3, 2*groupSize,
&cbResult,
0 );
CHECK( NT_SUCCESS( ntStatus ) && cbResult == 2*groupSize, "?" );
}
template<>
VOID
algImpDecryptPerfFunction< ImpCng, AlgDsa>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
{
NTSTATUS ntStatus;
UINT32 groupSize = dataSize <= 1024/8 ? 20 : 32;
ntStatus = BCryptVerifySignature( *(BCRYPT_KEY_HANDLE *) buf1,
NULL,
buf2, groupSize,
buf3, 2*groupSize,
0 );
CHECK( NT_SUCCESS( ntStatus ), "?" );
}
template<>
DsaImp<ImpCng, AlgDsa>::DsaImp()
{
m_perfDataFunction = &algImpDataPerfFunction <ImpCng, AlgDsa>;
m_perfDecryptFunction = &algImpDecryptPerfFunction<ImpCng, AlgDsa>;
m_perfKeyFunction = &algImpKeyPerfFunction <ImpCng, AlgDsa>;
m_perfCleanFunction = &algImpCleanPerfFunction<ImpCng, AlgDsa>;
state.hKey = NULL;
}
template<>
DsaImp<ImpCng, AlgDsa>::~DsaImp()
{
if( state.hKey != NULL )
{
CHECK( NT_SUCCESS( BCryptDestroyKey( state.hKey ) ), "?" );
state.hKey = NULL;
}
}
template<>
NTSTATUS
DsaImp<ImpCng, AlgDsa>::setKey( PCDLKEY_TESTBLOB pcKeyBlob )
{
NTSTATUS ntStatus = STATUS_SUCCESS;
BYTE buf[7 * DLKEY_MAXKEYSIZE ]; // Big enough for CNG header + fields of import blob
if( state.hKey != NULL )
{
CHECK( NT_SUCCESS( BCryptDestroyKey( state.hKey )), "?" );
state.hKey = NULL;
}
if( pcKeyBlob == NULL )
{
goto cleanup;
}
state.hKey = DsaKeyBlobToHandle( pcKeyBlob, buf );
state.cbP = pcKeyBlob->pGroup->cbPrimeP;
state.cbQ = pcKeyBlob->pGroup->cbPrimeQ;
ntStatus = state.hKey == NULL ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
cleanup:
return ntStatus;
}
template<>
NTSTATUS
DsaImp<ImpCng,AlgDsa>::sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig )
{
NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG cbResult;
if( cbHash != state.cbQ )
{
ntStatus = STATUS_NOT_SUPPORTED;
goto cleanup;
}
ntStatus = BCryptSignHash( state.hKey, NULL, (PBYTE)pbHash, (ULONG)cbHash, pbSig, (ULONG)cbSig, &cbResult, 0 );
CHECK( cbResult == cbSig, "Signature length mismatch" );
// Normalize the status code so that the MultiImp can directly compare two results
ntStatus = NT_SUCCESS( ntStatus ) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
cleanup:
return ntStatus;
}
template<>
NTSTATUS
DsaImp<ImpCng,AlgDsa>::verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig )
{
NTSTATUS ntStatus;
if( cbHash != state.cbQ )
{
ntStatus = STATUS_NOT_SUPPORTED;
goto cleanup;
}
ntStatus = BCryptVerifySignature( state.hKey,
NULL,
(PBYTE)pbHash, (ULONG)cbHash,
(PBYTE)pbSig, (ULONG)cbSig,
0 );
ntStatus = NT_SUCCESS( ntStatus ) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
cleanup:
return ntStatus;
}
// DSA end
/*
template<>
RsaSignImp<ImpCng, AlgRsaSignPkcs1>::~RsaSignImp()
{
if( state.hKey != NULL )
{
BCryptDestroyKey( state.hKey );
state.hKey = NULL;
}
}
template<>
NTSTATUS
RsaSignImp<ImpCng, AlgRsaSignPkcs1>::setKey( PCRSAKEY_TESTBLOB pcKeyBlob )
{
NTSTATUS ntStatus;
BCRYPT_RSAKEY_BLOB * pBlob = NULL;
PBYTE pTmp;
if( state.hKey != NULL )
{
BCryptDestroyKey( state.hKey );
state.hKey = NULL;
}
if( pcKeyBlob == NULL )
{
// Just used to clear the key state to do leak detection
return STATUS_SUCCESS;
}
// Allocate memory for our blob
pBlob = (BCRYPT_RSAKEY_BLOB *) malloc( sizeof( *pBlob ) + 8 + 3 * RSAKEY_MAXKEYSIZE );
CHECK( pBlob != NULL, "?" );
pBlob->Magic = BCRYPT_RSAPRIVATE_MAGIC;
pBlob->BitLength= pcKeyBlob->nBitsModulus;
pBlob->cbPublicExp = 8;
pBlob->cbModulus = pcKeyBlob->cbModulus;
pBlob->cbPrime1 = pcKeyBlob->cbPrime1;
pBlob->cbPrime2 = pcKeyBlob->cbPrime2;
pTmp = (PBYTE) (pBlob + 1);
SYMCRYPT_STORE_MSBFIRST64( pTmp, pcKeyBlob->u64PubExp );
pTmp += 8;
memcpy( pTmp, &pcKeyBlob->abModulus[0], pBlob->cbModulus );
pTmp += pBlob->cbModulus;
memcpy( pTmp, &pcKeyBlob->abPrime1[0], pBlob->cbPrime1 );
pTmp += pBlob->cbPrime1;
memcpy( pTmp, &pcKeyBlob->abPrime2[0], pBlob->cbPrime2 );
pTmp += pBlob->cbPrime2;
ntStatus = BCryptImportKeyPair(
BCRYPT_RSA_SIGN_ALG_HANDLE,
NULL,
BCRYPT_RSAPRIVATE_BLOB,
&state.hKey,
(PBYTE) pBlob,
(UINT32)(pTmp - (PBYTE) pBlob),
0 );
CHECK( NT_SUCCESS( ntStatus ), "?" );
return ntStatus;
}
template<>
NTSTATUS
RsaSignImp<ImpCng, AlgRsaSignPkcs1>::sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
PCSTR pcstrHashAlgName,
UINT32 u32Other,
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig )
{
NTSTATUS ntStatus;
BCRYPT_PKCS1_PADDING_INFO paddingInfo;
PCCNG_HASH_INFO pInfo;
ULONG cbResult;
UNREFERENCED_PARAMETER( u32Other );
pInfo = getHashInfo( pcstrHashAlgName);
paddingInfo.pszAlgId = pInfo->wideName;
ntStatus = BCryptSignHash(
state.hKey,
&paddingInfo,
(PBYTE) pbHash,
(UINT32)cbHash,
pbSig,
(UINT32)cbSig,
&cbResult,
BCRYPT_PAD_PKCS1 );
CHECK( NT_SUCCESS( ntStatus ) && cbResult == cbSig, "?" );
return ntStatus;
}
template<>
NTSTATUS
RsaSignImp<ImpCng, AlgRsaSignPkcs1>::verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig,
PCSTR pcstrHashAlgName,
UINT32 u32Other )
{
NTSTATUS ntStatus;
BCRYPT_PKCS1_PADDING_INFO paddingInfo;
PCCNG_HASH_INFO pInfo;
UNREFERENCED_PARAMETER( u32Other );
pInfo = getHashInfo( pcstrHashAlgName);
paddingInfo.pszAlgId = pInfo->wideName;
ntStatus = BCryptVerifySignature(
state.hKey,
&paddingInfo,
(PBYTE)pbHash,
(UINT32)cbHash,
(PBYTE)pbSig,
(UINT32)cbSig,
BCRYPT_PAD_PKCS1 );
return ntStatus;
}
*/
//===
/*
template<>
@ -3231,6 +3947,9 @@ addCngAlgs()
//addImplementationToGlobalList<RsaImp<ImpCng, AlgRsaVerifyPkcs1>>();
//addImplementationToGlobalList<RsaImp<ImpCng, AlgRsaSignPss>>();
//addImplementationToGlobalList<RsaImp<ImpCng, AlgRsaVerifyPss>>();
addImplementationToGlobalList<DhImp<ImpCng, AlgDh>>();
addImplementationToGlobalList<DsaImp<ImpCng, AlgDsa>>();
}
#endif //INCLUDE_IMPL_CNG

Просмотреть файл

@ -180,6 +180,8 @@ const char * AlgDsaVerify::name = "DsaVerify";
const char * AlgDh::name = "Dh";
const char * AlgDsa::name = "Dsa";
const char * AlgEcurveAllocate::name = "EcurveAllocate";
const char * AlgEcpointSetZero::name = "EcpointSetZero";
@ -495,9 +497,10 @@ const char * g_algorithmNames[] = {
//AlgRsaVerifyPkcs1::name,
AlgRsaSignPss::name,
//AlgRsaVerifyPss::name,
AlgDsaSign::name,
AlgDsaVerify::name,
//AlgDsaSign::name,
//AlgDsaVerify::name,
AlgDh::name,
AlgDsa::name,
AlgEcurveAllocate::name,
AlgEcpointSetZero::name,
AlgEcpointSetDistinguished::name,
@ -1161,9 +1164,9 @@ initTestInfrastructure( int argc, _In_reads_( argc ) char * argv[] )
}
} else {
//
// Disable the RSA32 implementation by default
// Disable the RSA32b implementation by default
//
updateNameSet( g_implementationNames, &g_implementationsToTest, '-', "rsa32" );
updateNameSet( g_implementationNames, &g_implementationsToTest, '-', "rsa32b" );
}
AllocWithChecksInit();
@ -1464,6 +1467,10 @@ runFunctionalTests()
testRsaEncAlgorithms();
testDhAlgorithms();
testDsaAlgorithms();
// need these two
#if SYMCRYPT_MS_VC
@ -1860,3 +1867,19 @@ printXmmRegisters( char * text )
}
#endif
VOID
ReverseMemCopy(
PBYTE pbDst,
PCBYTE pbSrc,
SIZE_T cbSrc
)
{
PBYTE p;
p = pbDst + cbSrc - 1;
while(p >= pbDst)
{
*p-- = *pbSrc++;
}
}

Просмотреть файл

@ -89,7 +89,7 @@ testMultiThread()
CHECK3( threads[i] != NULL, "Failed to start thread i", i)
}
Sleep( 1000 * 10 );
Sleep( 1000 * 5 );
g_fExitMultithreadTest = TRUE;

Просмотреть файл

@ -297,9 +297,10 @@ const ALG_MEASURE_PARAMS g_algMeasureParams[] =
"RsaSignPss" , 1, {128, 256, 384, 512}, {PERF_DATASIZE_SAME_AS_KEYSIZE},
"RsaVerifyPss" , 1, {128, 256, 384, 512}, {PERF_DATASIZE_SAME_AS_KEYSIZE},
"DsaSign" , 1, {64, 128, 256}, {},
"DsaVerify" , 1, {64, 128, 256}, {},
// "DsaSign" , 1, {64, 128, 256}, {},
// "DsaVerify" , 1, {64, 128, 256}, {},
"Dh" , 1, {64, 128, 256}, {PERF_DATASIZE_SAME_AS_KEYSIZE},
"Dsa" , 1, {64, 128, 256}, {PERF_DATASIZE_SAME_AS_KEYSIZE},
"EcurveAllocate" , 1, {PERF_KEY_NIST192, PERF_KEY_NIST224, PERF_KEY_NIST256, PERF_KEY_NIST384, PERF_KEY_NIST521, PERF_KEY_NUMS256, PERF_KEY_NUMS384, PERF_KEY_NUMS512, PERF_KEY_C255_19,}, {},
"EcpointSetZero" , 1, {PERF_KEY_NIST192, PERF_KEY_NIST224, PERF_KEY_NIST256, PERF_KEY_NIST384, PERF_KEY_NIST521, PERF_KEY_NUMS256, PERF_KEY_NUMS384, PERF_KEY_NUMS512,}, {},
@ -1376,4 +1377,4 @@ runRsaAverageKeyGenPerf()
}
iprint( "\n" );
}
#endif
#endif

Просмотреть файл

@ -5210,6 +5210,37 @@ RsaImp<ImpSc, AlgRsaVerifyPss>::~RsaImp()
//============================
VOID
DlgroupSetup( PBYTE buf1, SIZE_T keySize )
{
SYMCRYPT_ERROR scError;
PCDLGROUP_TESTBLOB pBlob = dlgroupForSize( keySize * 8 );
CHECK( pBlob != NULL, "?" );
PSYMCRYPT_DLGROUP pGroup = SymCryptDlgroupCreate( buf1 + 64, PERF_BUFFER_SIZE/2, pBlob->nBitsP, 8*pBlob->cbPrimeQ );
CHECK( pGroup != NULL, "Could not create group" );
scError = SymCryptDlgroupSetValue(
&pBlob->abPrimeP[0], pBlob->cbPrimeP,
pBlob->cbPrimeQ == 0 ? NULL : &pBlob->abPrimeQ[0], pBlob->cbPrimeQ,
&pBlob->abGenG[0], pBlob->cbPrimeP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
pBlob->pHashAlgorithm,
&pBlob->abSeed[0], pBlob->cbSeed,
pBlob->genCounter,
pBlob->fipsStandard,
pGroup );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error setting group values" );
*((PSYMCRYPT_DLGROUP *) buf1) = pGroup;
}
// Table with the DL groups sizes and pointers to the groups
struct {
SIZE_T keySize; // Always equal to cbPrimeP
@ -5330,6 +5361,7 @@ algImpKeyPerfFunction<ImpSc, AlgDsaSign>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SI
UNREFERENCED_PARAMETER( buf3 );
SetupDlGroup( buf1, keySize );
SetupSymCryptDsaAndDh( buf1, buf2, buf3 );
}
@ -5428,15 +5460,51 @@ DlImp<ImpSc, AlgDsaVerify>::~DlImp()
//============================
PSYMCRYPT_DLKEY
dlkeyObjectFromTestBlob( PCSYMCRYPT_DLGROUP pGroup, PCDLKEY_TESTBLOB pBlob )
{
PSYMCRYPT_DLKEY pRes;
SYMCRYPT_ERROR scError;
pRes = SymCryptDlkeyAllocate( pGroup );
CHECK( pRes != NULL, "?" );
scError = SymCryptDlkeySetValue( &pBlob->abPrivKey[0], pBlob->cbPrivKey,
&pBlob->abPubKey[0], pBlob->pGroup->cbPrimeP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
SYMCRYPT_FLAG_DLKEY_VERIFY, // Verify the key is correct
pRes );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error importing key" );
return pRes;
}
template<>
VOID
algImpKeyPerfFunction<ImpSc, AlgDh>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize )
{
UNREFERENCED_PARAMETER( buf2 );
SYMCRYPT_ERROR scError;
UNREFERENCED_PARAMETER( buf3 );
SetupDlGroup( buf1, keySize );
SetupSymCryptDsaAndDh( buf1, buf2, buf3 );
DlgroupSetup( buf1, keySize );
// Set up two keys in buf2
PSYMCRYPT_DLGROUP pGroup = *(PSYMCRYPT_DLGROUP *) buf1;
PSYMCRYPT_DLKEY pKey1 = SymCryptDlkeyCreate( buf2 + 64, PERF_BUFFER_SIZE/4, pGroup );
PSYMCRYPT_DLKEY pKey2 = SymCryptDlkeyCreate( buf2 + 64 + PERF_BUFFER_SIZE/4, PERF_BUFFER_SIZE/4, pGroup );
CHECK( pKey1 != NULL && pKey2 != NULL, "Failed to create keys" );
scError = SymCryptDlkeyGenerate( 0, pKey1 );
CHECK( scError == SYMCRYPT_NO_ERROR, "?" );
scError = SymCryptDlkeyGenerate( 0, pKey2 );
CHECK( scError == SYMCRYPT_NO_ERROR, "?" );
((PSYMCRYPT_DLKEY *) buf2)[0] = pKey1;
((PSYMCRYPT_DLKEY *) buf2)[1] = pKey2;
}
template<>
@ -5448,9 +5516,31 @@ algImpCleanPerfFunction<ImpSc, AlgDh>( PBYTE buf1, PBYTE buf2, PBYTE buf3 )
UNREFERENCED_PARAMETER( buf3 );
}
template<>
VOID
algImpDataPerfFunction< ImpSc, AlgDh>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
{
SYMCRYPT_ERROR scError;
UNREFERENCED_PARAMETER( buf2 );
UNREFERENCED_PARAMETER( dataSize );
PSYMCRYPT_DLGROUP pGroup = *(PSYMCRYPT_DLGROUP *) buf1;
PSYMCRYPT_DLKEY pKey = SymCryptDlkeyCreate( buf3, (1 << 16), pGroup );
CHECK( pKey != NULL, "?" );
scError = SymCryptDlkeyGenerate( 0, pKey );
CHECK( scError == SYMCRYPT_NO_ERROR, "?" );
scError = SymCryptDlkeyGetValue( pKey, NULL, 0, buf3 + (1 << 16), pGroup->cbPrimeP, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, 0 );
CHECK( scError == SYMCRYPT_NO_ERROR, "?" );
}
template<>
VOID
algImpDecryptPerfFunction< ImpSc, AlgDh>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
{
UNREFERENCED_PARAMETER( buf1 );
@ -5459,10 +5549,252 @@ algImpDataPerfFunction< ImpSc, AlgDh>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_
((PSYMCRYPT_DLKEY *) buf2)[1],
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0,
buf3 + sizeof(UINT32),
buf3,
dataSize ); // This will be the same as the key size
}
template<>
DhImp<ImpSc, AlgDh>::DhImp()
{
m_perfDataFunction = &algImpDataPerfFunction <ImpSc, AlgDh>;
m_perfDecryptFunction = &algImpDecryptPerfFunction< ImpSc, AlgDh>;
m_perfKeyFunction = &algImpKeyPerfFunction <ImpSc, AlgDh>;
m_perfCleanFunction = &algImpCleanPerfFunction<ImpSc, AlgDh>;
state.pGroup = NULL;
state.pKey = NULL;
}
template<>
DhImp<ImpSc, AlgDh>::~DhImp()
{
if( state.pKey != NULL )
{
SymCryptDlkeyFree( state.pKey );
state.pKey = NULL;
}
if( state.pGroup != NULL )
{
SymCryptDlgroupFree( state.pGroup );
state.pGroup = NULL;
}
}
template<>
NTSTATUS
DhImp<ImpSc, AlgDh>::setKey( _In_ PCDLKEY_TESTBLOB pcKeyBlob )
{
if( state.pKey != NULL )
{
SymCryptDlkeyFree( state.pKey );
state.pKey = NULL;
}
if( state.pGroup != NULL )
{
SymCryptDlgroupFree( state.pGroup );
state.pGroup = NULL;
}
if( pcKeyBlob != NULL )
{
state.pGroup = dlgroupObjectFromTestBlob( pcKeyBlob->pGroup );
state.pKey = dlkeyObjectFromTestBlob( state.pGroup, pcKeyBlob );
CHECK( state.pGroup != NULL && state.pKey != NULL, "?" );
}
return STATUS_SUCCESS;
}
template<>
NTSTATUS
DhImp<ImpSc, AlgDh>::sharedSecret(
_In_ PCDLKEY_TESTBLOB pcPubkey,
_Out_writes_( cbSecret ) PBYTE pbSecret,
SIZE_T cbSecret )
{
PSYMCRYPT_DLKEY pKey2;
SYMCRYPT_ERROR scError;
pKey2 = dlkeyObjectFromTestBlob( state.pGroup, pcPubkey );
CHECK( pKey2 != NULL, "?")
scError = SymCryptDhSecretAgreement( state.pKey,
pKey2,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0,
pbSecret, cbSecret );
SymCryptDlkeyFree( pKey2 );
return scError == SYMCRYPT_NO_ERROR ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
template<>
VOID
algImpKeyPerfFunction<ImpSc, AlgDsa>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize )
{
SYMCRYPT_ERROR scError;
UNREFERENCED_PARAMETER( buf3 );
DlgroupSetup( buf1, keySize ); // Set buf1 to contain a DL group of size keySize
// Set up a keys in buf2
PSYMCRYPT_DLGROUP pGroup = *(PSYMCRYPT_DLGROUP *) buf1;
PSYMCRYPT_DLKEY pKey = SymCryptDlkeyCreate( buf2 + 64, PERF_BUFFER_SIZE/4, pGroup );
CHECK( pKey != NULL, "Failed to create key" );
scError = SymCryptDlkeyGenerate( 0, pKey );
CHECK( scError == SYMCRYPT_NO_ERROR, "?" );
((PSYMCRYPT_DLKEY *) buf2)[0] = pKey;
}
template<>
VOID
algImpCleanPerfFunction<ImpSc, AlgDsa>( PBYTE buf1, PBYTE buf2, PBYTE buf3 )
{
UNREFERENCED_PARAMETER( buf1 );
UNREFERENCED_PARAMETER( buf2 );
UNREFERENCED_PARAMETER( buf3 );
}
template<>
VOID
algImpDataPerfFunction< ImpSc, AlgDsa>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
{
SYMCRYPT_ERROR scError;
UNREFERENCED_PARAMETER( dataSize );
PSYMCRYPT_DLKEY pKey = *(PSYMCRYPT_DLKEY *) buf2;
PSYMCRYPT_DLGROUP pGroup = *(PSYMCRYPT_DLGROUP *) buf1;
scError = SymCryptDsaSign( pKey,
buf3, 32,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0,
buf3 + 64, 2 * pGroup->cbPrimeQ );
CHECK( scError == SYMCRYPT_NO_ERROR, "?" );
}
template<>
VOID
algImpDecryptPerfFunction< ImpSc, AlgDsa>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
{
SYMCRYPT_ERROR scError;
UNREFERENCED_PARAMETER( dataSize );
PSYMCRYPT_DLKEY pKey = *(PSYMCRYPT_DLKEY *) buf2;
PSYMCRYPT_DLGROUP pGroup = *(PSYMCRYPT_DLGROUP *) buf1;
scError = SymCryptDsaVerify(pKey,
buf3, 32,
buf3 + 64, 2 * pGroup->cbPrimeQ,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0 );
CHECK( scError == SYMCRYPT_NO_ERROR, "?" );
}
template<>
DsaImp<ImpSc, AlgDsa>::DsaImp()
{
m_perfDataFunction = &algImpDataPerfFunction <ImpSc, AlgDsa>;
m_perfDecryptFunction = &algImpDecryptPerfFunction< ImpSc, AlgDsa>;
m_perfKeyFunction = &algImpKeyPerfFunction <ImpSc, AlgDsa>;
m_perfCleanFunction = &algImpCleanPerfFunction<ImpSc, AlgDsa>;
state.pGroup = NULL;
state.pKey = NULL;
}
template<>
DsaImp<ImpSc, AlgDsa>::~DsaImp()
{
if( state.pKey != NULL )
{
SymCryptDlkeyFree( state.pKey );
state.pKey = NULL;
}
if( state.pGroup != NULL )
{
SymCryptDlgroupFree( state.pGroup );
state.pGroup = NULL;
}
}
template<>
NTSTATUS
DsaImp<ImpSc, AlgDsa>::setKey( _In_ PCDLKEY_TESTBLOB pcKeyBlob )
{
if( state.pKey != NULL )
{
SymCryptDlkeyFree( state.pKey );
state.pKey = NULL;
}
if( state.pGroup != NULL )
{
SymCryptDlgroupFree( state.pGroup );
state.pGroup = NULL;
}
if( pcKeyBlob != NULL )
{
state.pGroup = dlgroupObjectFromTestBlob( pcKeyBlob->pGroup );
state.pKey = dlkeyObjectFromTestBlob( state.pGroup, pcKeyBlob );
CHECK( state.pGroup != NULL && state.pKey != NULL, "?" );
}
return STATUS_SUCCESS;
}
template<>
NTSTATUS
DsaImp<ImpSc, AlgDsa>::sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash, // Can be any size, but often = size of Q
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig )
{
SYMCRYPT_ERROR scError;
scError = SymCryptDsaSign( state.pKey,
pbHash, cbHash,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0,
pbSig, cbSig );
return scError == SYMCRYPT_NO_ERROR ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
template<>
NTSTATUS
DsaImp<ImpSc, AlgDsa>::verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig )
{
SYMCRYPT_ERROR scError;
scError = SymCryptDsaVerify( state.pKey,
pbHash, cbHash,
pbSig, cbSig,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0 );
return scError == SYMCRYPT_NO_ERROR ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
}
template<>
DlImp<ImpSc, AlgDh>::DlImp()
{
@ -6511,9 +6843,12 @@ addSymCryptAlgs()
//addImplementationToGlobalList<RsaImp<ImpSc, AlgRsaSignPss>>();
//addImplementationToGlobalList<RsaImp<ImpSc, AlgRsaVerifyPss>>();
addImplementationToGlobalList<DlImp<ImpSc, AlgDsaSign>>();
addImplementationToGlobalList<DlImp<ImpSc, AlgDsaVerify>>();
addImplementationToGlobalList<DlImp<ImpSc, AlgDh>>();
addImplementationToGlobalList<DhImp<ImpSc, AlgDh>>();
addImplementationToGlobalList<DsaImp<ImpSc, AlgDsa>>();
//addImplementationToGlobalList<DlImp<ImpSc, AlgDsaSign>>();
//addImplementationToGlobalList<DlImp<ImpSc, AlgDsaVerify>>();
//addImplementationToGlobalList<DlImp<ImpSc, AlgDh>>();
addImplementationToGlobalList<ArithImp<ImpSc, AlgTrialDivisionContext>>();
addImplementationToGlobalList<ArithImp<ImpSc, AlgTrialDivision>>();

Просмотреть файл

@ -71,6 +71,8 @@ SOURCES= \
testScsTools.cpp \
testRsaSign.cpp \
testRsaEnc.cpp \
testDh.cpp \
testDsa.cpp \
I386_SOURCES = \
savexmm.asm \

711
unittest/lib/testDh.cpp Normal file
Просмотреть файл

@ -0,0 +1,711 @@
//
// TestDh.cpp
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "precomp.h"
DLGROUP_TESTBLOB g_DlGroup[ MAX_TEST_DLGROUPS ] = {0};
UINT32 g_nDlgroups = 0;
// Creating DL groups for all DH and DSA tests that need random groups
VOID
addOneDlgroup( UINT32 nBitsP, BOOL randomQsize )
{
// nBitsP = size of P
SYMCRYPT_ERROR scError;
PCSYMCRYPT_HASH hashAlgorithm;
SYMCRYPT_DLGROUP_FIPS fipsStandard;
UINT32 nBitsQ = 0;
CHECK( g_nDlgroups < MAX_TEST_DLGROUPS, "?" );
CHECK3( nBitsP >= 160 && nBitsP <= 4096 , "Bad parameters %d", nBitsP );
// We must pick a random nBitsQ, fips standard, and hash algorithm that satisfy the requirements.
// We do this the easy and brute-force way:
// Generate a random combination and try again if we fail any of the criteria
for(;;) {
BYTE b = g_rng.byte();
fipsStandard = SYMCRYPT_DLGROUP_FIPS_NONE;
switch( b % 3 )
{
case 0:
fipsStandard = SYMCRYPT_DLGROUP_FIPS_NONE;
break;
case 1:
fipsStandard = SYMCRYPT_DLGROUP_FIPS_186_2;
break;
case 2:
fipsStandard = SYMCRYPT_DLGROUP_FIPS_186_3;
}
hashAlgorithm = NULL;
switch( b % 5 )
{
case 0: hashAlgorithm = SymCryptSha1Algorithm; break;
case 1: hashAlgorithm = SymCryptSha256Algorithm; break;
case 2: hashAlgorithm = SymCryptSha384Algorithm; break;
case 3: hashAlgorithm = SymCryptSha512Algorithm; break;
case 4: hashAlgorithm = NULL; break;
}
// Hash algorithm defaults to SHA-1
SIZE_T nBitsHash = hashAlgorithm == NULL ? 160 : 8 * SymCryptHashResultSize( hashAlgorithm );
if( randomQsize )
{
nBitsQ = (UINT32) g_rng.sizet( 128, hashAlgorithm != NULL ? nBitsHash + 1 : nBitsP );
} else {
nBitsQ = 0;
}
// Fail if hash alg is provided for FIPS 186-2 or not for any other mode
if( (fipsStandard == SYMCRYPT_DLGROUP_FIPS_186_2 && hashAlgorithm != NULL ) ||
(fipsStandard != SYMCRYPT_DLGROUP_FIPS_186_2 && hashAlgorithm == NULL ) )
{
continue;
}
// Fail if P is smaller than the hash size
if( nBitsP < nBitsHash )
{
continue;
}
// Fail if nBitsQ > hash size
if( (nBitsQ > 0 && nBitsQ > nBitsHash) ||
(nBitsQ == 0 && nBitsP > 1024 && nBitsHash < 256 ) )
{
continue;
}
break;
}
//iprint( "[%d, %d, %d, %d]", nBitsP, nBitsQ, hashAlgorithm == NULL ? 0 : SymCryptHashResultSize( hashAlgorithm ), fipsStandard );
PSYMCRYPT_DLGROUP pGroup = SymCryptDlgroupAllocate( nBitsP, nBitsQ );
CHECK( pGroup != NULL, "?" );
scError = SymCryptDlgroupGenerate( hashAlgorithm, fipsStandard, pGroup );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error generating DL group" );
PDLGROUP_TESTBLOB pBlob = &g_DlGroup[ g_nDlgroups++ ];
SymCryptWipe( (PBYTE) pBlob, sizeof( *pBlob ) );
SIZE_T cbP;
SIZE_T cbQ;
SIZE_T cbSeed;
SymCryptDlgroupGetSizes( pGroup,
&cbP,
&cbQ,
NULL,
&cbSeed );
pBlob->cbPrimeP = (UINT32) cbP;
pBlob->cbPrimeQ = (UINT32) cbQ;
pBlob->cbSeed = (UINT32)cbSeed;
pBlob->nBitsP = nBitsP;
scError = SymCryptDlgroupGetValue( pGroup,
&pBlob->abPrimeP[0], pBlob->cbPrimeP,
&pBlob->abPrimeQ[0], pBlob->cbPrimeQ,
&pBlob->abGenG[0], pBlob->cbPrimeP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
&pBlob->pHashAlgorithm,
&pBlob->abSeed[0], pBlob->cbSeed,
&pBlob->genCounter );
CHECK( scError == SYMCRYPT_NO_ERROR, "Failure to get DLGROUP value" );
SymCryptDlgroupFree( pGroup );
pGroup = NULL;
}
VOID generateDlGroups()
{
// Fill up our array of key blobs with generated keys
UINT32 desiredFixedGroupSizes[] = {
(4096 << 16) + 1, // 1 keys of 4096 bits
(3072 << 16) + 2, // 2 keys of 3072 bits
(2048 << 16) + 5,
(1536 << 16) + 2,
(1024 << 16) + 5,
(768 << 16) + 2,
(512 << 16) + 2,
0,
};
UINT32 bitSize;
char * sep = " [group gen: ";
UINT32 previousSize = 0;
if( g_nDlgroups >= MAX_TEST_DLGROUPS )
{
goto cleanup;
}
for( int i = 0; desiredFixedGroupSizes[i] != 0; i++ )
{
bitSize = desiredFixedGroupSizes[i] >> 16;
int n = desiredFixedGroupSizes[i] & 0xff;
while( n-- && g_nDlgroups < MAX_TEST_DLGROUPS )
{
if( bitSize == previousSize )
{
iprint( "." );
} else {
iprint( "%s%d", sep, bitSize );
sep = ",";
previousSize = bitSize;
}
addOneDlgroup( bitSize, FALSE );
}
}
// And we fill the rest with randomly-sized keys
// For performance we favor the smaller key sizes.
while( g_nDlgroups < MAX_TEST_DLGROUPS )
{
UINT32 r = g_rng.uint32();
// We use prime moduli as they are almost independent
if( (r % 51) == 0 )
{
bitSize = (UINT32) g_rng.sizet( 2048, 4096 );
} else if ( (r % 5) == 0 ) {
bitSize = (UINT32) g_rng.sizet( 1024, 2049 );
} else {
bitSize = (UINT32) g_rng.sizet( 512, 1025 );
}
if( bitSize == previousSize )
{
iprint( "." );
} else {
iprint( "%s%d", sep, bitSize );
sep = ",";
previousSize = bitSize;
}
addOneDlgroup( bitSize, TRUE );
}
iprint( "]" );
cleanup:
return;
}
PSYMCRYPT_DLGROUP
dlgroupObjectFromTestBlob( PCDLGROUP_TESTBLOB pBlob )
{
SYMCRYPT_ERROR scError;
PSYMCRYPT_DLGROUP pGroup = NULL;
pGroup = SymCryptDlgroupAllocate( pBlob->nBitsP, 8*pBlob->cbPrimeQ );
CHECK( pGroup != NULL, "Could not create group" );
scError = SymCryptDlgroupSetValue(
&pBlob->abPrimeP[0], pBlob->cbPrimeP,
pBlob->cbPrimeQ == 0 ? NULL : &pBlob->abPrimeQ[0], pBlob->cbPrimeQ,
&pBlob->abGenG[0], pBlob->cbPrimeP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
pBlob->pHashAlgorithm,
pBlob->cbSeed == 0 ? NULL : &pBlob->abSeed[0], pBlob->cbSeed,
pBlob->genCounter,
pBlob->fipsStandard,
pGroup );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error setting group values" );
return pGroup;
}
PCDLGROUP_TESTBLOB
dlgroupRandom()
{
return &g_DlGroup[ g_rng.sizet( g_nDlgroups ) ];
}
PCDLGROUP_TESTBLOB
dlgroupForSize( SIZE_T nBits )
{
for( UINT32 i=0; i<g_nDlgroups; i++ )
{
if( g_DlGroup[i].nBitsP == nBits )
{
return &g_DlGroup[i];
}
}
CHECK3( FALSE, "Could not find group for %d bits", nBits );
return NULL;
}
class DhMultiImp: public DhImplementation
{
public:
DhMultiImp( String algName ); // AlgName not needed, but kept for symmetry with other algorithm classes
~DhMultiImp();
private:
DhMultiImp( const DhMultiImp & );
VOID operator=( const DhMultiImp & );
public:
typedef std::vector<DhImplementation *> ImpPtrVector;
ImpPtrVector m_imps; // Implementations being tested
ImpPtrVector m_comps; // Implementations for current computation
virtual NTSTATUS setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob ); // Returns an error if this key can't be handled.
virtual NTSTATUS sharedSecret(
_In_ PCDLKEY_TESTBLOB pcPubkey, // Must be on same group
_Out_writes_( cbSecret ) PBYTE pbSecret,
SIZE_T cbSecret );
};
DhMultiImp::DhMultiImp( String algName )
{
m_algorithmName = algName;
getAllImplementations<DhImplementation>( algName, &m_imps );
}
DhMultiImp::~DhMultiImp()
{
//
// Propagate the # KAT failures to the individual algorithms.
//
for( ImpPtrVector::iterator i = m_imps.begin(); i != m_imps.end(); ++i )
{
(*i)->m_nErrorKatFailure += m_nErrorKatFailure;
}
}
NTSTATUS
DhMultiImp::setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob )
{
m_comps.clear();
for( ImpPtrVector::iterator i = m_imps.begin(); i != m_imps.end(); ++i )
{
if( (*i)->setKey( pcKeyBlob ) == STATUS_SUCCESS )
{
m_comps.push_back( *i );
}
}
return m_comps.size() == 0 ? STATUS_NOT_SUPPORTED : STATUS_SUCCESS;
}
NTSTATUS
DhMultiImp::sharedSecret(
_In_ PCDLKEY_TESTBLOB pcPubkey, // Must be on same group
_Out_writes_( cbSecret ) PBYTE pbSecret,
SIZE_T cbSecret )
{
BYTE buf[ DLKEY_MAXKEYSIZE ];
NTSTATUS ntStatus;
ResultMerge res;
CHECK( cbSecret <= DLKEY_MAXKEYSIZE, "?" );
for( ImpPtrVector::iterator i = m_comps.begin(); i != m_comps.end(); ++i )
{
buf[0]++;
ntStatus = (*i)->sharedSecret( pcPubkey, buf, cbSecret );
CHECK( NT_SUCCESS( ntStatus ), "Error computing shared DH secret" );
res.addResult( *i, buf, cbSecret );
}
res.getResult( pbSecret, cbSecret );
return STATUS_SUCCESS;
}
VOID
createKatFileSingleDh( FILE * f, PCDLGROUP_TESTBLOB pBlob )
{
SYMCRYPT_ERROR scError;
BYTE buf[ DLKEY_MAXKEYSIZE ];
BYTE privKey[ DLKEY_MAXKEYSIZE ];
PSYMCRYPT_DLGROUP pGroup = dlgroupObjectFromTestBlob( pBlob );
PSYMCRYPT_DLKEY pKey1 = SymCryptDlkeyAllocate( pGroup );
PSYMCRYPT_DLKEY pKey2 = SymCryptDlkeyAllocate( pGroup );
scError = SymCryptDlkeyGenerate( 0, pKey1 );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error generating DH key" );
scError = SymCryptDlkeyGenerate( 0, pKey2 );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error generating DH key" );
UINT32 cbPrivKey1 = SymCryptDlkeySizeofPrivateKey( pKey1 );
UINT32 cbPrivKey2 = SymCryptDlkeySizeofPrivateKey( pKey2 );
fprintf( f, "P = " );
fprintHex( f, pBlob->abPrimeP, pBlob->cbPrimeP );
fprintf( f, "G = " );
fprintHex( f, pBlob->abGenG, pBlob->cbPrimeP );
if( pBlob->cbPrimeQ > 0 )
{
fprintf( f, "Q = " );
fprintHex( f, pBlob->abPrimeQ, pBlob->cbPrimeQ );
}
scError = SymCryptDlkeyGetValue( pKey1,
privKey, cbPrivKey1,
buf, pBlob->cbPrimeP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0 );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error reading DH key" );
fprintf( f, "X1 = " );
fprintHex( f, privKey, cbPrivKey1 );
fprintf( f, "H1 = " );
fprintHex( f, buf, pBlob->cbPrimeP );
scError = SymCryptDlkeyGetValue( pKey2,
privKey, cbPrivKey2,
buf, pBlob->cbPrimeP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0 );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error reading DH key" );
fprintf( f, "X2 = " );
fprintHex( f, privKey, cbPrivKey2 );
fprintf( f, "H2 = " );
fprintHex( f, buf, pBlob->cbPrimeP );
scError = SymCryptDhSecretAgreement( pKey1,
pKey2,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0,
buf, pBlob->cbPrimeP );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error creating shared secret" );
fprintf( f, "SS = " );
fprintHex( f, buf, pBlob->cbPrimeP );
scError = SymCryptDhSecretAgreement( pKey2,
pKey1,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0,
privKey, pBlob->cbPrimeP );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error creating shared secret" );
CHECK( memcmp( buf, privKey, pBlob->cbPrimeP ) == 0, "Shared secret disagreement" );
fprintf( f, "\n" );
SymCryptDlkeyFree( pKey1 );
pKey1 = NULL;
SymCryptDlkeyFree( pKey2 );
pKey2 = NULL;
SymCryptDlgroupFree( pGroup );
pGroup = NULL;
}
VOID
createKatFileDh()
// This function is not normally used, but available for use whenever we want to re-generate
// new test vectors.
{
FILE * f = fopen( "generated_kat_dh.dat", "wt" );
CHECK( f != NULL, "Could not create output file" );
fprintf( f, "#\n"
"# DO NOT EDIT: Generated test vectors for DH\n"
"#\n"
"\n"
);
fprintf( f, "[Dh]\n\n" );
generateDlGroups();
for( int i=0; i<MAX_TEST_DLGROUPS; i++ )
{
createKatFileSingleDh( f, &g_DlGroup[ i ] );
}
fprintf( f, "\n"
"rnd = 1\n"
"\n"
);
fclose( f );
// Generating test vectors is not normal program flow, so we abort here to avoid getting into
// non-standard states.
CHECK( FALSE, "Written DH test vector file" );
}
VOID
testDhSingle(
DhImplementation * pDh,
_In_ PCDLKEY_TESTBLOB pKey1,
_In_ PCDLKEY_TESTBLOB pKey2,
_In_reads_( cbShared ) PCBYTE pbShared,
SIZE_T cbShared )
{
NTSTATUS ntStatus;
BYTE buf[DLKEY_MAXKEYSIZE];
// We require that two keys are on the same group objects; we don't have the case where we
// have to compare two groups to see if they are the same.
CHECK( pKey1->pGroup == pKey2->pGroup, "Two DH keys are on different DL group objects" );
SIZE_T cbP = pKey1->pGroup->cbPrimeP;
CHECK( cbP <= DLKEY_MAXKEYSIZE, "?" );
CHECK( cbShared == cbP, "Wrong shared secret size" );
ntStatus = pDh->setKey( pKey1 );
CHECK( NT_SUCCESS( ntStatus ), "Error setting key" );
ntStatus = pDh->sharedSecret( pKey2, buf, cbP );
CHECK( NT_SUCCESS( ntStatus ), "Error getting shared secret" );
CHECK( memcmp( buf, pbShared, cbP ) == 0, "Shared secret mismatch" );
ntStatus = pDh->setKey( pKey2 );
CHECK( NT_SUCCESS( ntStatus ), "Error setting key" );
ntStatus = pDh->sharedSecret( pKey1, buf, cbP );
CHECK( NT_SUCCESS( ntStatus ), "Error getting shared secret" );
CHECK( memcmp( buf, pbShared, cbP ) == 0, "Shared secret mismatch" );
CHECK( pDh->setKey( NULL ) == STATUS_SUCCESS, "Failed to clear key" );
}
VOID
testDhtestGroups( DhImplementation * pDh, INT64 line )
{
BYTE buf1[DLKEY_MAXKEYSIZE];
BYTE buf2[DLKEY_MAXKEYSIZE];
SYMCRYPT_ERROR scError;
NTSTATUS ntStatus;
UNREFERENCED_PARAMETER( line );
generateDlGroups();
for( int i=0; i<MAX_TEST_DLGROUPS; i++ )
{
PCDLGROUP_TESTBLOB pGroupBlob = &g_DlGroup[i];
// We have a group; to test the DH implementation we need to create two keys
PSYMCRYPT_DLGROUP pGroup = SymCryptDlgroupAllocate( pGroupBlob->nBitsP, 8*pGroupBlob->cbPrimeQ );
CHECK( pGroup != NULL, "Error allocating Symcr")
SIZE_T cbP = pGroupBlob->cbPrimeP;
scError = SymCryptDlgroupSetValue(
&pGroupBlob->abPrimeP[0], cbP,
&pGroupBlob->abPrimeQ[0], pGroupBlob->cbPrimeQ,
&pGroupBlob->abGenG[0], cbP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
pGroupBlob->pHashAlgorithm,
&pGroupBlob->abSeed[0], pGroupBlob->cbSeed,
pGroupBlob->genCounter,
pGroupBlob->fipsStandard,
pGroup );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error setting group object" );
PSYMCRYPT_DLKEY pKey1 = SymCryptDlkeyAllocate( pGroup );
PSYMCRYPT_DLKEY pKey2 = SymCryptDlkeyAllocate( pGroup );
CHECK( pKey1 != NULL && pKey2 != NULL, "Could not create keys" );
scError = SymCryptDlkeyGenerate( 0, pKey1 );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error generating key" );
scError = SymCryptDlkeyGenerate( SYMCRYPT_FLAG_DLKEY_GEN_MODP, pKey2 );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error generating key" );
DLKEY_TESTBLOB blob1;
DLKEY_TESTBLOB blob2;
blob1.pGroup = pGroupBlob;
blob2.pGroup = pGroupBlob;
blob1.cbPrivKey = SymCryptDlkeySizeofPrivateKey( pKey1 );
blob2.cbPrivKey = SymCryptDlkeySizeofPrivateKey( pKey2 );
scError = SymCryptDlkeyGetValue(
pKey1,
&blob1.abPrivKey[0], blob1.cbPrivKey,
&blob1.abPubKey[0], cbP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0 );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error exporting key" );
scError = SymCryptDlkeyGetValue(
pKey2,
&blob2.abPrivKey[0], blob2.cbPrivKey,
&blob2.abPubKey[0], cbP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0 );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error exporting key" );
GENRANDOM( buf1, sizeof( buf1 ) );
GENRANDOM( buf2, sizeof( buf2 ) );
ntStatus = pDh->setKey( &blob1 );
CHECK( NT_SUCCESS( ntStatus ), "Error setting key" );
ntStatus = pDh->sharedSecret( &blob2, buf1, cbP );
CHECK( NT_SUCCESS( ntStatus ), "Error getting secret" );
ntStatus = pDh->setKey( &blob2 );
CHECK( NT_SUCCESS( ntStatus ), "Error setting key" );
ntStatus = pDh->sharedSecret( &blob1, buf2, cbP );
CHECK( NT_SUCCESS( ntStatus ), "Error getting secret" );
CHECK( memcmp( buf1, buf2, cbP ) == 0, "Shared secret mismatch" );
SymCryptDlkeyFree( pKey1 );
pKey1 = NULL;
SymCryptDlkeyFree( pKey2 );
pKey2 = NULL;
SymCryptDlgroupFree( pGroup );
pGroup = NULL;
}
// Clear the key
pDh->setKey( NULL );
}
VOID
testDhKats()
{
// fix this.
KatData *katDh = getCustomResource( "kat_dh.dat", "KAT_DH" );
KAT_ITEM katItem;
static String g_currentCategory;
BOOL skipData = TRUE;
String sep = " ";
BOOL doneAnything = FALSE;
std::auto_ptr<DhMultiImp> pDhMultiImp;
while( 1 )
{
katDh->getKatItem( & katItem );
if( katItem.type == KAT_TYPE_END )
{
break;
}
if( katItem.type == KAT_TYPE_CATEGORY )
{
g_currentCategory = katItem.categoryName;
pDhMultiImp.reset( new DhMultiImp( g_currentCategory ) );
//
// If we have no algorithms, we skip all the data until the next category
//
skipData = (pDhMultiImp->m_imps.size() == 0);
if( !skipData )
{
iprint( "%s%s", sep.c_str(), g_currentCategory.c_str() );
sep = ", ";
doneAnything = TRUE;
}
//print( "%s, %d\n", g_currentCategory.c_str(), pDhMultiImp->m_imps.size() );
}
if( katItem.type == KAT_TYPE_DATASET && !skipData )
{
if( katIsFieldPresent( katItem, "p" ) )
{
BString P = katParseData( katItem, "p" );
BString G = katParseData( katItem, "g" );
BString Q;
if( katIsFieldPresent( katItem, "q" ) )
{
Q = katParseData( katItem, "q" );
}
BString X1 = katParseData( katItem, "x1" );
BString H1 = katParseData( katItem, "h1" );
BString X2 = katParseData( katItem, "x2" );
BString H2 = katParseData( katItem, "h2" );
BString secret = katParseData( katItem, "ss" );
DLGROUP_TESTBLOB bGroup = {0};
DLKEY_TESTBLOB bKey1;
DLKEY_TESTBLOB bKey2;
bGroup.nBitsP = (UINT32) P.size() * 8;
bGroup.cbPrimeP = (UINT32) P.size();
bGroup.cbPrimeQ = (UINT32) Q.size();
CHECK( G.size() == bGroup.cbPrimeP, "Generator length mismatch" );
memcpy( bGroup.abPrimeP, P.data(), bGroup.cbPrimeP );
memcpy( bGroup.abPrimeQ, Q.data(), bGroup.cbPrimeQ );
memcpy( bGroup.abGenG, G.data(), bGroup.cbPrimeP );
bKey1.pGroup = &bGroup;
bKey2.pGroup = &bGroup;
bKey1.cbPrivKey = (UINT32) X1.size();
bKey2.cbPrivKey = (UINT32) X2.size();
CHECK( H1.size() == bGroup.cbPrimeP && H2.size() == bGroup.cbPrimeP, "Wrong public key sizes" );
memcpy( bKey1.abPubKey, H1.data(), bGroup.cbPrimeP );
memcpy( bKey2.abPubKey, H2.data(), bGroup.cbPrimeP );
memcpy( bKey1.abPrivKey, X1.data(), bKey1.cbPrivKey );
memcpy( bKey2.abPrivKey, X2.data(), bKey2.cbPrivKey );
testDhSingle( pDhMultiImp.get(), &bKey1, &bKey2, secret.data(), secret.size() );
} else if( katIsFieldPresent( katItem, "rnd" ) )
{
generateDlGroups();
testDhtestGroups( pDhMultiImp.get(), katItem.line );
} else {
CHECK( FALSE, "Invalid KAT record" );
}
}
}
if( doneAnything )
{
iprint( "\n" );
}
delete katDh;
}
VOID
testDhAlgorithms()
{
String sep;
// Uncomment this function to generate a new KAT file
//createKatFileDh();
testDhKats();
CHECK3( g_nOutstandingCheckedAllocs == 0, "Memory leak %d", g_nOutstandingCheckedAllocs );
}

535
unittest/lib/testDsa.cpp Normal file
Просмотреть файл

@ -0,0 +1,535 @@
//
// TestDsa.cpp
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
#include "precomp.h"
class DsaMultiImp: public DsaImplementation
{
public:
DsaMultiImp( String algName ); // AlgName not needed, but kept for symmetry with other algorithm classes
~DsaMultiImp();
private:
DsaMultiImp( const DsaMultiImp & );
VOID operator=( const DsaMultiImp & );
public:
typedef std::vector<DsaImplementation *> ImpPtrVector;
virtual NTSTATUS setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob ); // Returns an error if this key can't be handled.
virtual NTSTATUS sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash, // Can be any size, but often = size of Q
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig ); // cbSig == cbModulus of group
virtual NTSTATUS verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig );
ImpPtrVector m_imps; // Implementations being tested
ImpPtrVector m_comps; // Implementations for current computation
};
DsaMultiImp::DsaMultiImp( String algName )
{
m_algorithmName = algName;
getAllImplementations<DsaImplementation>( algName, &m_imps );
}
DsaMultiImp::~DsaMultiImp()
{
//
// Propagate the # KAT failures to the individual algorithms.
//
for( ImpPtrVector::iterator i = m_imps.begin(); i != m_imps.end(); ++i )
{
(*i)->m_nErrorKatFailure += m_nErrorKatFailure;
}
}
NTSTATUS
DsaMultiImp::setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob )
{
m_comps.clear();
for( ImpPtrVector::iterator i = m_imps.begin(); i != m_imps.end(); ++i )
{
if( (*i)->setKey( pcKeyBlob ) == STATUS_SUCCESS )
{
m_comps.push_back( *i );
}
}
return m_comps.size() == 0 ? STATUS_NOT_SUPPORTED : STATUS_SUCCESS;
}
NTSTATUS
DsaMultiImp::sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig )
{
// DSA signatures are not deterministic so we do the following:
// - Have every implementation sign
// - Have every implementation verify each signature
// - return a random signature
BYTE sig[ DLKEY_MAXKEYSIZE ];
int nSigs = 0;
NTSTATUS ntStatus;
CHECK( cbSig <= sizeof( sig ), "?" );
for( ImpPtrVector::iterator i = m_comps.begin(); i != m_comps.end(); ++i )
{
sig[0]++;
ntStatus = (*i)->sign( pbHash, cbHash, &sig[0], cbSig );
if( ntStatus == STATUS_NOT_SUPPORTED )
{
continue;
}
CHECK( ntStatus == STATUS_SUCCESS, "Failure during DSA signature" );
for( ImpPtrVector::iterator j = m_comps.begin(); j != m_comps.end(); ++j )
{
ntStatus = (*j)->verify( pbHash, cbHash, &sig[0], cbSig );
if( ntStatus == STATUS_NOT_SUPPORTED )
{
continue;
}
CHECK4( ntStatus == STATUS_SUCCESS, "DSA sig verification failure %s, %s",
(*i)->m_implementationName.c_str(),
(*j)->m_implementationName.c_str() );
}
// Copy a random sig to the output
nSigs += 1;
if( (g_rng.byte() % nSigs) == 0 )
{
memcpy( pbSig, &sig[0], cbSig );
}
}
return STATUS_SUCCESS;
}
NTSTATUS
DsaMultiImp::verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig )
{
ResultMerge res;
NTSTATUS ntStatus;
BYTE b[4];
for( ImpPtrVector::iterator i = m_comps.begin(); i != m_comps.end(); ++i )
{
ntStatus = (*i)->verify( pbHash, cbHash, pbSig, cbSig );
if( ntStatus == STATUS_NOT_SUPPORTED )
{
continue;
}
SYMCRYPT_STORE_MSBFIRST32( b, ntStatus );
res.addResult( *i, b, 4 );
}
res.getResult( b, 4 );
ntStatus = SYMCRYPT_LOAD_MSBFIRST32( b );
return ntStatus;
}
VOID
createKatFileSingleDsa( FILE * f, PCDLGROUP_TESTBLOB pBlob )
{
SYMCRYPT_ERROR scError;
BYTE buf[ DLKEY_MAXKEYSIZE ];
BYTE sig[ DLKEY_MAXKEYSIZE ];
BYTE privKey[ DLKEY_MAXKEYSIZE ];
PSYMCRYPT_DLGROUP pGroup = dlgroupObjectFromTestBlob( pBlob );
PSYMCRYPT_DLKEY pKey = SymCryptDlkeyAllocate( pGroup );
scError = SymCryptDlkeyGenerate( 0, pKey );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error generating DL key" );
UINT32 cbPrivKey = SymCryptDlkeySizeofPrivateKey( pKey );
fprintf( f, "P = " );
fprintHex( f, pBlob->abPrimeP, pBlob->cbPrimeP );
fprintf( f, "G = " );
fprintHex( f, pBlob->abGenG, pBlob->cbPrimeP );
CHECK( pBlob->cbPrimeQ > 0, "Can't do DSA without having Q" );
fprintf( f, "Q = " );
fprintHex( f, pBlob->abPrimeQ, pBlob->cbPrimeQ );
scError = SymCryptDlkeyGetValue( pKey,
privKey, cbPrivKey,
buf, pBlob->cbPrimeP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0 );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error reading DL key" );
fprintf( f, "X = " );
fprintHex( f, privKey, cbPrivKey );
fprintf( f, "H = " );
fprintHex( f, buf, pBlob->cbPrimeP );
UINT32 r = g_rng.uint32();
UINT32 cbHash = 0;
// Pick a random hash size.
//
switch( r % 11)
{
case 0: cbHash = 20; break;
case 1: cbHash = 32; break;
case 2: cbHash = 48; break;
case 3: cbHash = 64; break;
case 4: cbHash = (r % 59) + 6; break; // 59 is prime, so this is orthoginal to the switch case
case 5: case 6: case 7: case 8: case 9: case 10:
cbHash = pBlob->cbPrimeQ; // Customary and only size that CNG supports
break;
default: CHECK( FALSE, "?" );
}
GENRANDOM( buf, cbHash );
scError = SymCryptDsaSign( pKey,
buf, cbHash,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0,
sig, 2 * pBlob->cbPrimeQ );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error signing DSA" );
fprintf( f, "Hash = " );
fprintHex( f, buf, cbHash );
fprintf( f, "Sig = " );
fprintHex( f, sig, 2 * pBlob->cbPrimeQ );
fprintf( f, "\n" );
SymCryptDlkeyFree( pKey );
pKey = NULL;
SymCryptDlgroupFree( pGroup );
pGroup = NULL;
}
VOID
createKatFileDsa()
// This function is not normally used, but available for use whenever we want to re-generate
// new test vectors.
{
FILE * f = fopen( "generated_kat_dsa.dat", "wt" );
CHECK( f != NULL, "Could not create output file" );
fprintf( f, "#\n"
"# DO NOT EDIT: Generated test vectors for DSA\n"
"#\n"
"\n"
);
fprintf( f, "[Dsa]\n\n" );
generateDlGroups();
for( int i=0; i<MAX_TEST_DLGROUPS; i++ )
{
if( g_DlGroup[i].cbPrimeQ != 0 )
{
createKatFileSingleDsa( f, &g_DlGroup[ i ] );
}
}
fprintf( f, "\n"
"rnd = 1\n"
"\n"
);
fclose( f );
// Generating test vectors is not normal program flow, so we abort here to avoid getting into
// non-standard states.
CHECK( FALSE, "Written DSA test vector file" );
}
VOID
testDsaSingle(
DsaImplementation * pDsa,
_In_ PCDLKEY_TESTBLOB pKey,
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig,
UINT64 line )
{
NTSTATUS ntStatus;
BYTE buf[DLKEY_MAXKEYSIZE];
UNREFERENCED_PARAMETER( line );
// iprint( "<%d>", (UINT32)line );
CHECK( cbHash < DLKEY_MAXKEYSIZE && cbSig < DLKEY_MAXKEYSIZE, "?" );
SIZE_T cbP = pKey->pGroup->cbPrimeP;
CHECK( cbP <= DLKEY_MAXKEYSIZE, "?" );
ntStatus = pDsa->setKey( pKey );
CHECK( NT_SUCCESS( ntStatus ), "Error setting key" );
ntStatus = pDsa->verify( pbHash, cbHash, pbSig, cbSig );
CHECK( NT_SUCCESS( ntStatus ), "Error verifying DSA signature" );
// We have to be careful with modifying the hash value.
// DSA truncates the hash, so the modification must be within the range of Q
// As the truncation is to the bit size, we introduce a difference in the bytes
// that are always relevant.
memcpy( buf, pbHash, cbHash );
buf[g_rng.sizet( min( cbHash, pKey->pGroup->cbPrimeQ - 1 ) )]++;
ntStatus = pDsa->verify( buf, cbHash, pbSig, cbSig );
CHECK( !NT_SUCCESS( ntStatus ), "Success verifying modified DSA signature" );
memcpy( buf, pbHash, cbSig );
buf[g_rng.sizet( cbSig )]++;
ntStatus = pDsa->verify( pbHash, cbHash, buf, cbSig );
CHECK( !NT_SUCCESS( ntStatus ), "Success verifying modified DSA signature" );
CHECK( pDsa->setKey( NULL ) == STATUS_SUCCESS, "Failed to clear key" );
}
VOID
testDsatestGroups( DsaImplementation * pDsa, INT64 line )
{
BYTE hash[DLKEY_MAXKEYSIZE];
BYTE sig[DLKEY_MAXKEYSIZE];
SYMCRYPT_ERROR scError;
NTSTATUS ntStatus;
UNREFERENCED_PARAMETER( line );
generateDlGroups();
for( int i=0; i<MAX_TEST_DLGROUPS; i++ )
{
PCDLGROUP_TESTBLOB pGroupBlob = &g_DlGroup[i];
// We have a group; generate a key
PSYMCRYPT_DLGROUP pGroup = SymCryptDlgroupAllocate( pGroupBlob->nBitsP, 8*pGroupBlob->cbPrimeQ );
CHECK( pGroup != NULL, "Error allocating Symcr")
SIZE_T cbP = pGroupBlob->cbPrimeP;
scError = SymCryptDlgroupSetValue(
&pGroupBlob->abPrimeP[0], cbP,
&pGroupBlob->abPrimeQ[0], pGroupBlob->cbPrimeQ,
&pGroupBlob->abGenG[0], cbP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
pGroupBlob->pHashAlgorithm,
&pGroupBlob->abSeed[0], pGroupBlob->cbSeed,
pGroupBlob->genCounter,
pGroupBlob->fipsStandard,
pGroup );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error setting group object" );
PSYMCRYPT_DLKEY pKey = SymCryptDlkeyAllocate( pGroup );
CHECK( pKey != NULL, "Could not create keys" );
scError = SymCryptDlkeyGenerate( 0, pKey );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error generating key" );
DLKEY_TESTBLOB blob;
blob.pGroup = pGroupBlob;
blob.cbPrivKey = SymCryptDlkeySizeofPrivateKey( pKey );
scError = SymCryptDlkeyGetValue(
pKey,
&blob.abPrivKey[0], blob.cbPrivKey,
&blob.abPubKey[0], cbP,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0 );
CHECK( scError == SYMCRYPT_NO_ERROR, "Error exporting key" );
ntStatus = pDsa->setKey( &blob );
CHECK( NT_SUCCESS( ntStatus ), "Error setting key" );
UINT32 r = g_rng.uint32();
UINT32 cbHash = 0;
switch( r % 11)
{
case 0: cbHash = 20; break;
case 1: cbHash = 32; break;
case 2: cbHash = 48; break;
case 3: cbHash = 64; break;
case 4: cbHash = (r % 59) + 6; break; // 59 is prime, so this is orthoginal to the switch case
case 5: case 6: case 7: case 8: case 9: case 10:
cbHash = pGroupBlob->cbPrimeQ; // Customary and only size that CNG supports
break;
default: CHECK( FALSE, "?" );
}
GENRANDOM( hash, cbHash );
UINT32 cbSig = 2 * pGroupBlob->cbPrimeQ;
CHECK( cbSig > 0, "?" );
ntStatus = pDsa->sign( hash, cbHash, sig, cbSig );
CHECK( NT_SUCCESS( ntStatus ), "?" );
// Modify the hash, but only in the bytes that are known to be used
SIZE_T j = g_rng.sizet( min( cbHash, pGroupBlob->cbPrimeQ - 1) );
hash[j]++;
ntStatus = pDsa->verify( hash, cbHash, sig, cbSig );
hash[j]--;
CHECK( !NT_SUCCESS( ntStatus ), "?" );
j = g_rng.sizet( cbSig );
sig[j]--;
ntStatus = pDsa->verify( hash, cbHash, sig, cbSig );
sig[j]++;
CHECK( !NT_SUCCESS( ntStatus ), "?" );
ntStatus = pDsa->verify( hash, cbHash, sig, cbSig );
CHECK( NT_SUCCESS( ntStatus ), "?" );
SymCryptDlkeyFree( pKey );
pKey = NULL;
SymCryptDlgroupFree( pGroup );
pGroup = NULL;
}
// Clear the key
pDsa->setKey( NULL );
}
VOID
testDsaKats()
{
// fix this.
KatData *katDsa = getCustomResource( "kat_dsa.dat", "KAT_DSA" );
KAT_ITEM katItem;
static String g_currentCategory;
BOOL skipData = TRUE;
String sep = " ";
BOOL doneAnything = FALSE;
std::auto_ptr<DsaMultiImp> pDsaMultiImp;
while( 1 )
{
katDsa->getKatItem( & katItem );
if( katItem.type == KAT_TYPE_END )
{
break;
}
if( katItem.type == KAT_TYPE_CATEGORY )
{
g_currentCategory = katItem.categoryName;
pDsaMultiImp.reset( new DsaMultiImp( g_currentCategory ) );
//
// If we have no algorithms, we skip all the data until the next category
//
skipData = (pDsaMultiImp->m_imps.size() == 0);
if( !skipData )
{
iprint( "%s%s", sep.c_str(), g_currentCategory.c_str() );
sep = ", ";
doneAnything = TRUE;
}
//print( "%s, %d\n", g_currentCategory.c_str(), pDsaMultiImp->m_imps.size() );
}
if( katItem.type == KAT_TYPE_DATASET && !skipData )
{
if( katIsFieldPresent( katItem, "p" ) )
{
BString P = katParseData( katItem, "p" );
BString G = katParseData( katItem, "g" );
BString Q = katParseData( katItem, "q" );
BString X = katParseData( katItem, "x" );
BString H = katParseData( katItem, "h" );
BString Hash = katParseData( katItem, "hash" );
BString Sig = katParseData( katItem, "sig" );
DLGROUP_TESTBLOB bGroup = {0};
DLKEY_TESTBLOB bKey;
bGroup.nBitsP = (UINT32) P.size() * 8;
bGroup.cbPrimeP = (UINT32) P.size();
bGroup.cbPrimeQ = (UINT32) Q.size();
CHECK( G.size() == bGroup.cbPrimeP, "Generator length mismatch" );
memcpy( bGroup.abPrimeP, P.data(), bGroup.cbPrimeP );
memcpy( bGroup.abPrimeQ, Q.data(), bGroup.cbPrimeQ );
memcpy( bGroup.abGenG, G.data(), bGroup.cbPrimeP );
bKey.pGroup = &bGroup;
bKey.cbPrivKey = (UINT32) X.size();
CHECK( H.size() == bGroup.cbPrimeP, "Wrong public key sizes" );
memcpy( bKey.abPubKey, H.data(), bGroup.cbPrimeP );
memcpy( bKey.abPrivKey, X.data(), bKey.cbPrivKey );
testDsaSingle( pDsaMultiImp.get(), &bKey, Hash.data(), Hash.size(), Sig.data(), Sig.size(), katItem.line );
} else if( katIsFieldPresent( katItem, "rnd" ) )
{
generateDlGroups();
testDsatestGroups( pDsaMultiImp.get(), katItem.line );
} else {
CHECK( FALSE, "Invalid KAT record" );
}
}
}
if( doneAnything )
{
iprint( "\n" );
}
delete katDsa;
}
VOID
testDsaAlgorithms()
{
// Uncomment this function to generate a new KAT file
// createKatFileDsa();
testDsaKats();
CHECK3( g_nOutstandingCheckedAllocs == 0, "Memory leak %d", g_nOutstandingCheckedAllocs );
}

Просмотреть файл

@ -120,6 +120,7 @@ RsaEncMultiImp::setKey( PCRSAKEY_TESTBLOB pcKeyBlob )
// Process result as MSBfirst array to get errors to print correctly.
for( ImpPtrVector::iterator i = m_comps.begin(); i != m_comps.end(); ++i )
{
msg[0]++;
ntStatus = (*i)->decrypt( pbCiphertext, cbCiphertext,
pcstrHashAlgName,
pbLabel, cbLabel,
@ -172,6 +173,7 @@ RsaEncMultiImp::encrypt(
{
for( ImpPtrVector::iterator j = m_comps.begin(); j != m_comps.end(); j++ )
{
msg[0]++;
ntStatus = (*j)->decrypt( ciphertext, cbCiphertext, pcstrHashAlgName, pbLabel, cbLabel, msg, sizeof( msg ), &cbMsgRes );
CHECK( ntStatus == STATUS_SUCCESS, "Failure during RSA decryption" );
CHECK( cbMsgRes == cbMsg, "Wrong message length" );

Просмотреть файл

@ -233,7 +233,7 @@ VOID rsaTestKeysGenerate()
};
UINT32 bitSize;
char * sep = " RSA test key gen: ";
char * sep = " [test key gen: ";
UINT32 previousSize = 0;
if( g_nRsaTestKeyBlobs >= MAX_RSA_TESTKEYS )
@ -252,7 +252,7 @@ VOID rsaTestKeysGenerate()
iprint( "." );
} else {
iprint( "%s%d", sep, bitSize );
sep = ", ";
sep = ",";
previousSize = bitSize;
}
@ -283,7 +283,7 @@ VOID rsaTestKeysGenerate()
iprint( "." );
} else {
iprint( "%s%d", sep, bitSize );
sep = ", ";
sep = ",";
previousSize = bitSize;
}
rsaTestKeysAddOne( bitSize );
@ -292,11 +292,11 @@ VOID rsaTestKeysGenerate()
while( g_nRsaTestKeyBlobs < MAX_RSA_TESTKEYS )
{
bitSize = (UINT32) g_rng.sizet( 3 * 512, 6 * 512 );
iprint( ", F%d", bitSize );
iprint( ",F%d", bitSize );
rsaTestKeysAddOneFunky( bitSize );
}
iprint( "\n" );
iprint( "]" );
cleanup:
return;
@ -478,6 +478,7 @@ RsaSignMultiImp::sign(
for( ImpPtrVector::iterator i = m_comps.begin(); i != m_comps.end(); ++i )
{
sig[0]++;
ntStatus = (*i)->sign( pbHash, cbHash, pcstrHashAlgName, u32Other, &sig[0], m_cbSig );
CHECK( ntStatus == STATUS_SUCCESS, "Failure during RSA signature" );
for( ImpPtrVector::iterator j = m_comps.begin(); j != m_comps.end(); ++j )

Просмотреть файл

@ -16,7 +16,8 @@ kat_ecdsa.dat KAT_ECDSA "..\kat_ecdsa.da
kat_IEEE802_11SaeCustom.dat KAT_SAE_CUSTOM "..\kat_IEEE802_11SaeCustom.dat"
kat_rsaSign.dat KAT_RSA_SIGN "..\kat_rsaSign.dat"
kat_rsaEnc.dat KAT_RSA_ENC "..\kat_rsaEnc.dat"
kat_dh.dat KAT_DH "..\kat_dh.dat"
kat_dsa.dat KAT_DSA "..\kat_dsa.dat"