From f5a7daf2bba08406718b4cddc22523cc672f8adc Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Thu, 14 May 2020 00:02:32 +0000 Subject: [PATCH] sidh: update to p434 --- dh/doc.go | 1 + dh/sidh/api.go | 227 --- dh/sidh/doc.go | 11 + dh/sidh/internal/common/doc.go | 2 + dh/sidh/internal/common/params.go | 24 + dh/sidh/internal/common/types.go | 106 ++ dh/sidh/internal/common/utils.go | 46 + dh/sidh/internal/isogeny/curve_ops.go | 440 ------ dh/sidh/internal/isogeny/types.go | 145 -- dh/sidh/internal/p434/arith_amd64.s | 1232 +++++++++++++++++ dh/sidh/internal/p434/arith_amd64_test.go | 96 ++ dh/sidh/internal/p434/arith_decl.go | 45 + dh/sidh/internal/p434/arith_generic.go | 192 +++ dh/sidh/internal/p434/arith_test.go | 101 ++ dh/sidh/internal/p434/core.go | 282 ++++ dh/sidh/internal/p434/curve.go | 362 +++++ dh/sidh/internal/p434/curve_test.go | 100 ++ dh/sidh/internal/p434/fp2.go | 195 +++ dh/sidh/internal/p434/fp2_test.go | 245 ++++ dh/sidh/internal/p434/params.go | 197 +++ dh/sidh/internal/p434/params_test.go | 69 + dh/sidh/{ => internal}/p503/arith_amd64.s | 118 +- .../{ => internal}/p503/arith_amd64_test.go | 24 +- dh/sidh/{ => internal}/p503/arith_arm64.s | 79 +- dh/sidh/{ => internal}/p503/arith_decl.go | 25 +- dh/sidh/internal/p503/arith_generic.go | 192 +++ dh/sidh/internal/p503/arith_test.go | 101 ++ dh/sidh/internal/p503/core.go | 282 ++++ dh/sidh/internal/p503/curve.go | 362 +++++ dh/sidh/internal/p503/curve_test.go | 100 ++ dh/sidh/internal/p503/doc.go | 2 + dh/sidh/internal/p503/fp2.go | 195 +++ dh/sidh/internal/p503/fp2_test.go | 245 ++++ dh/sidh/internal/p503/params.go | 203 +++ dh/sidh/internal/p503/params_test.go | 73 + dh/sidh/{ => internal}/p751/arith_amd64.s | 223 +-- dh/sidh/internal/p751/arith_amd64_test.go | 140 ++ dh/sidh/{ => internal}/p751/arith_arm64.s | 106 +- dh/sidh/internal/p751/arith_decl.go | 45 + dh/sidh/internal/p751/arith_generic.go | 192 +++ dh/sidh/internal/p751/arith_test.go | 101 ++ dh/sidh/internal/p751/core.go | 282 ++++ dh/sidh/internal/p751/curve.go | 362 +++++ dh/sidh/internal/p751/curve_test.go | 100 ++ dh/sidh/internal/p751/doc.go | 2 + dh/sidh/internal/p751/fp2.go | 195 +++ dh/sidh/internal/p751/fp2_test.go | 245 ++++ dh/sidh/internal/p751/params.go | 249 ++++ dh/sidh/internal/p751/params_test.go | 74 + dh/sidh/internal/templates/arith_decl.gotemp | 45 + .../internal/templates/arith_generic.gotemp | 192 +++ dh/sidh/internal/templates/arith_test.gotemp | 101 ++ dh/sidh/internal/templates/core.gotemp | 282 ++++ dh/sidh/internal/templates/curve.gotemp | 362 +++++ dh/sidh/internal/templates/curve_test.gotemp | 100 ++ dh/sidh/internal/templates/fp2.gotemp | 195 +++ dh/sidh/internal/templates/fp2_test.gotemp | 245 ++++ dh/sidh/internal/templates/gen.go | 106 ++ dh/sidh/p503/arith_generic.go | 197 --- dh/sidh/p503/arith_test.go | 341 ----- dh/sidh/p503/consts.go | 178 --- dh/sidh/p503/curve_test.go | 139 -- dh/sidh/p503/field_ops.go | 249 ---- dh/sidh/p503/isogeny_test.go | 101 -- dh/sidh/p503/utils_test.go | 335 ----- dh/sidh/p751/arith_decl.go | 44 - dh/sidh/p751/arith_generic.go | 196 --- dh/sidh/p751/arith_test.go | 322 ----- dh/sidh/p751/consts.go | 227 --- dh/sidh/p751/curve_test.go | 192 --- dh/sidh/p751/field_ops.go | 253 ---- dh/sidh/p751/isogeny_test.go | 130 -- dh/sidh/p751/utils_test.go | 340 ----- dh/sidh/params.go | 82 -- dh/sidh/sidh.go | 555 ++++---- dh/sidh/sidh_test.go | 626 ++++++--- dh/sidh/sike.go | 262 ++++ dh/sidh/sike_test.go | 579 ++++++++ dh/sidh/testdata/PQCkemKAT_374.rsp | 702 ++++++++++ dh/sidh/testdata/PQCkemKAT_434.rsp | 702 ++++++++++ dh/sidh/testdata/PQCkemKAT_644.rsp | 702 ++++++++++ go.mod | 6 +- 82 files changed, 12544 insertions(+), 4979 deletions(-) create mode 100644 dh/doc.go delete mode 100644 dh/sidh/api.go create mode 100644 dh/sidh/doc.go create mode 100644 dh/sidh/internal/common/doc.go create mode 100644 dh/sidh/internal/common/params.go create mode 100644 dh/sidh/internal/common/types.go create mode 100644 dh/sidh/internal/common/utils.go delete mode 100644 dh/sidh/internal/isogeny/curve_ops.go delete mode 100644 dh/sidh/internal/isogeny/types.go create mode 100644 dh/sidh/internal/p434/arith_amd64.s create mode 100644 dh/sidh/internal/p434/arith_amd64_test.go create mode 100644 dh/sidh/internal/p434/arith_decl.go create mode 100644 dh/sidh/internal/p434/arith_generic.go create mode 100644 dh/sidh/internal/p434/arith_test.go create mode 100644 dh/sidh/internal/p434/core.go create mode 100644 dh/sidh/internal/p434/curve.go create mode 100644 dh/sidh/internal/p434/curve_test.go create mode 100644 dh/sidh/internal/p434/fp2.go create mode 100644 dh/sidh/internal/p434/fp2_test.go create mode 100644 dh/sidh/internal/p434/params.go create mode 100644 dh/sidh/internal/p434/params_test.go rename dh/sidh/{ => internal}/p503/arith_amd64.s (94%) rename dh/sidh/{ => internal}/p503/arith_amd64_test.go (87%) rename dh/sidh/{ => internal}/p503/arith_arm64.s (90%) rename dh/sidh/{ => internal}/p503/arith_decl.go (57%) create mode 100644 dh/sidh/internal/p503/arith_generic.go create mode 100644 dh/sidh/internal/p503/arith_test.go create mode 100644 dh/sidh/internal/p503/core.go create mode 100644 dh/sidh/internal/p503/curve.go create mode 100644 dh/sidh/internal/p503/curve_test.go create mode 100644 dh/sidh/internal/p503/doc.go create mode 100644 dh/sidh/internal/p503/fp2.go create mode 100644 dh/sidh/internal/p503/fp2_test.go create mode 100644 dh/sidh/internal/p503/params.go create mode 100644 dh/sidh/internal/p503/params_test.go rename dh/sidh/{ => internal}/p751/arith_amd64.s (93%) create mode 100644 dh/sidh/internal/p751/arith_amd64_test.go rename dh/sidh/{ => internal}/p751/arith_arm64.s (92%) create mode 100644 dh/sidh/internal/p751/arith_decl.go create mode 100644 dh/sidh/internal/p751/arith_generic.go create mode 100644 dh/sidh/internal/p751/arith_test.go create mode 100644 dh/sidh/internal/p751/core.go create mode 100644 dh/sidh/internal/p751/curve.go create mode 100644 dh/sidh/internal/p751/curve_test.go create mode 100644 dh/sidh/internal/p751/doc.go create mode 100644 dh/sidh/internal/p751/fp2.go create mode 100644 dh/sidh/internal/p751/fp2_test.go create mode 100644 dh/sidh/internal/p751/params.go create mode 100644 dh/sidh/internal/p751/params_test.go create mode 100644 dh/sidh/internal/templates/arith_decl.gotemp create mode 100644 dh/sidh/internal/templates/arith_generic.gotemp create mode 100644 dh/sidh/internal/templates/arith_test.gotemp create mode 100644 dh/sidh/internal/templates/core.gotemp create mode 100644 dh/sidh/internal/templates/curve.gotemp create mode 100644 dh/sidh/internal/templates/curve_test.gotemp create mode 100644 dh/sidh/internal/templates/fp2.gotemp create mode 100644 dh/sidh/internal/templates/fp2_test.gotemp create mode 100644 dh/sidh/internal/templates/gen.go delete mode 100644 dh/sidh/p503/arith_generic.go delete mode 100644 dh/sidh/p503/arith_test.go delete mode 100644 dh/sidh/p503/consts.go delete mode 100644 dh/sidh/p503/curve_test.go delete mode 100644 dh/sidh/p503/field_ops.go delete mode 100644 dh/sidh/p503/isogeny_test.go delete mode 100644 dh/sidh/p503/utils_test.go delete mode 100644 dh/sidh/p751/arith_decl.go delete mode 100644 dh/sidh/p751/arith_generic.go delete mode 100644 dh/sidh/p751/arith_test.go delete mode 100644 dh/sidh/p751/consts.go delete mode 100644 dh/sidh/p751/curve_test.go delete mode 100644 dh/sidh/p751/field_ops.go delete mode 100644 dh/sidh/p751/isogeny_test.go delete mode 100644 dh/sidh/p751/utils_test.go delete mode 100644 dh/sidh/params.go create mode 100644 dh/sidh/sike.go create mode 100644 dh/sidh/sike_test.go create mode 100644 dh/sidh/testdata/PQCkemKAT_374.rsp create mode 100644 dh/sidh/testdata/PQCkemKAT_434.rsp create mode 100644 dh/sidh/testdata/PQCkemKAT_644.rsp diff --git a/dh/doc.go b/dh/doc.go new file mode 100644 index 0000000..6867766 --- /dev/null +++ b/dh/doc.go @@ -0,0 +1 @@ +package dh diff --git a/dh/sidh/api.go b/dh/sidh/api.go deleted file mode 100644 index bd5d588..0000000 --- a/dh/sidh/api.go +++ /dev/null @@ -1,227 +0,0 @@ -package sidh - -import ( - "errors" - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - "io" -) - -// I keep it bool in order to be able to apply logical NOT -type KeyVariant uint - -// Id's correspond to bitlength of the prime field characteristic -// Currently FP_751 is the only one supported by this implementation -const ( - FP_503 uint8 = iota - FP_751 - FP_964 - maxPrimeFieldId -) - -const ( - // First 2 bits identify SIDH variant third bit indicates - // wether key is a SIKE variant (set) or SIDH (not set) - - // 001 - SIDH: corresponds to 2-torsion group - KeyVariant_SIDH_A KeyVariant = 1 << 0 - // 010 - SIDH: corresponds to 3-torsion group - KeyVariant_SIDH_B = 1 << 1 - // 110 - SIKE - KeyVariant_SIKE = 1<<2 | KeyVariant_SIDH_B -) - -// Base type for public and private key. Used mainly to carry domain -// parameters. -type key struct { - // Domain parameters of the algorithm to be used with a key - params *SidhParams - // Flag indicates wether corresponds to 2-, 3-torsion group or SIKE - keyVariant KeyVariant -} - -// Defines operations on public key -type PublicKey struct { - key - affine_xP Fp2Element - affine_xQ Fp2Element - affine_xQmP Fp2Element -} - -// Defines operations on private key -type PrivateKey struct { - key - // Secret key - Scalar []byte - // Used only by KEM - S []byte -} - -// Accessor to the domain parameters -func (key *key) Params() *SidhParams { - return key.params -} - -// Accessor to key variant -func (key *key) Variant() KeyVariant { - return key.keyVariant -} - -// NewPrivateKey initializes private key. -// Usage of this function guarantees that the object is correctly initialized. -func NewPrivateKey(id uint8, v KeyVariant) *PrivateKey { - prv := &PrivateKey{key: key{params: Params(id), keyVariant: v}} - if (v & KeyVariant_SIDH_A) == KeyVariant_SIDH_A { - prv.Scalar = make([]byte, prv.params.A.SecretByteLen) - } else { - prv.Scalar = make([]byte, prv.params.B.SecretByteLen) - } - if v == KeyVariant_SIKE { - prv.S = make([]byte, prv.params.MsgLen) - } - return prv -} - -// NewPublicKey initializes public key. -// Usage of this function guarantees that the object is correctly initialized. -func NewPublicKey(id uint8, v KeyVariant) *PublicKey { - return &PublicKey{key: key{params: Params(id), keyVariant: v}} -} - -// Import clears content of the public key currently stored in the structure -// and imports key stored in the byte string. Returns error in case byte string -// size is wrong. Doesn't perform any validation. -func (pub *PublicKey) Import(input []byte) error { - if len(input) != pub.Size() { - return errors.New("sidh: input to short") - } - op := CurveOperations{Params: pub.params} - ssSz := pub.params.SharedSecretSize - op.Fp2FromBytes(&pub.affine_xP, input[0:ssSz]) - op.Fp2FromBytes(&pub.affine_xQ, input[ssSz:2*ssSz]) - op.Fp2FromBytes(&pub.affine_xQmP, input[2*ssSz:3*ssSz]) - return nil -} - -// Exports currently stored key. In case structure hasn't been filled with key data -// returned byte string is filled with zeros. -func (pub *PublicKey) Export() []byte { - output := make([]byte, pub.params.PublicKeySize) - op := CurveOperations{Params: pub.params} - ssSz := pub.params.SharedSecretSize - op.Fp2ToBytes(output[0:ssSz], &pub.affine_xP) - op.Fp2ToBytes(output[ssSz:2*ssSz], &pub.affine_xQ) - op.Fp2ToBytes(output[2*ssSz:3*ssSz], &pub.affine_xQmP) - return output -} - -// Size returns size of the public key in bytes -func (pub *PublicKey) Size() int { - return pub.params.PublicKeySize -} - -// Exports currently stored key. In case structure hasn't been filled with key data -// returned byte string is filled with zeros. -func (prv *PrivateKey) Export() []byte { - ret := make([]byte, len(prv.Scalar)+len(prv.S)) - copy(ret, prv.S) - copy(ret[len(prv.S):], prv.Scalar) - return ret -} - -// Size returns size of the private key in bytes -func (prv *PrivateKey) Size() int { - tmp := len(prv.Scalar) - if prv.Variant() == KeyVariant_SIKE { - tmp += int(prv.params.MsgLen) - } - return tmp -} - -// Import clears content of the private key currently stored in the structure -// and imports key from octet string. In case of SIKE, the random value 'S' -// must be prepended to the value of actual private key (see SIKE spec for details). -// Function doesn't import public key value to PrivateKey object. -func (prv *PrivateKey) Import(input []byte) error { - if len(input) != prv.Size() { - return errors.New("sidh: input to short") - } - copy(prv.S, input[:len(prv.S)]) - copy(prv.Scalar, input[len(prv.S):]) - return nil -} - -// Generates random private key for SIDH or SIKE. Generated value is -// formed as little-endian integer from key-space <2^(e2-1)..2^e2 - 1> -// for KeyVariant_A or <2^(s-1)..2^s - 1>, where s = ceil(log_2(3^e3)), -// for KeyVariant_B. -// -// Returns error in case user provided RNG fails. -func (prv *PrivateKey) Generate(rand io.Reader) error { - var err error - var dp *DomainParams - - if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A { - dp = &prv.params.A - } else { - dp = &prv.params.B - } - - //err = prv.generatePrivateKey(rand) - if prv.keyVariant == KeyVariant_SIKE && err == nil { - _, err = io.ReadFull(rand, prv.S) - } - - // Private key generation takes advantage of the fact that keyspace for secret - // key is (0, 2^x - 1), for some possitivite value of 'x' (see SIKE, 1.3.8). - // It means that all bytes in the secret key, but the last one, can take any - // value between <0x00,0xFF>. Similarily for the last byte, but generation - // needs to chop off some bits, to make sure generated value is an element of - // a key-space. - _, err = io.ReadFull(rand, prv.Scalar) - if err != nil { - return err - } - prv.Scalar[len(prv.Scalar)-1] &= (1 << (dp.SecretBitLen % 8)) - 1 - // Make sure scalar is SecretBitLen long. SIKE spec says that key - // space starts from 0, but I'm not confortable with having low - // value scalars used for private keys. It is still secrure as per - // table 5.1 in [SIKE]. - prv.Scalar[len(prv.Scalar)-1] |= 1 << ((dp.SecretBitLen % 8) - 1) - return err -} - -// Generates public key. -// -// Constant time. -func (prv *PrivateKey) GeneratePublicKey() *PublicKey { - if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A { - return publicKeyGenA(prv) - } - return publicKeyGenB(prv) -} - -// Computes a shared secret which is a j-invariant. Function requires that pub has -// different KeyVariant than prv. Length of returned output is 2*ceil(log_2 P)/8), -// where P is a prime defining finite field. -// -// It's important to notice that each keypair must not be used more than once -// to calculate shared secret. -// -// Function may return error. This happens only in case provided input is invalid. -// Constant time for properly initialized private and public key. -func DeriveSecret(prv *PrivateKey, pub *PublicKey) ([]byte, error) { - - if (pub == nil) || (prv == nil) { - return nil, errors.New("sidh: invalid arguments") - } - - if (pub.keyVariant == prv.keyVariant) || (pub.params.Id != prv.params.Id) { - return nil, errors.New("sidh: public and private are incompatbile") - } - - if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A { - return deriveSecretA(prv, pub), nil - } else { - return deriveSecretB(prv, pub), nil - } -} diff --git a/dh/sidh/doc.go b/dh/sidh/doc.go new file mode 100644 index 0000000..85a5acc --- /dev/null +++ b/dh/sidh/doc.go @@ -0,0 +1,11 @@ +// Package sidh provides implementation of experimental post-quantum +// Supersingular Isogeny Diffie-Hellman (SIDH) as well as Supersingular +// Isogeny Key Encapsulation (SIKE). +// +// Code is based on implementation from https://github.com/cloudflare/circl +// +// References: +// - [SIDH] https://eprint.iacr.org/2011/506 +// - [SIKE] http://www.sike.org/files/SIDH-spec.pdf +// +package sidh diff --git a/dh/sidh/internal/common/doc.go b/dh/sidh/internal/common/doc.go new file mode 100644 index 0000000..f606f42 --- /dev/null +++ b/dh/sidh/internal/common/doc.go @@ -0,0 +1,2 @@ +// Package common provides types, variables, constants and functions commonly used in SIDH or SIKE. +package common diff --git a/dh/sidh/internal/common/params.go b/dh/sidh/internal/common/params.go new file mode 100644 index 0000000..3be1c45 --- /dev/null +++ b/dh/sidh/internal/common/params.go @@ -0,0 +1,24 @@ +package common + +import "fmt" + +// Keeps mapping: SIDH prime field ID to domain parameters +var sidhParams = make(map[uint8]SidhParams) + +// Params returns domain parameters corresponding to finite field and identified by +// `id` provieded by the caller. Function panics in case `id` wasn't registered earlier. +func Params(id uint8) *SidhParams { + if val, ok := sidhParams[id]; ok { + return &val + } + panic("sidh: SIDH Params ID unregistered") +} + +// Registers SIDH parameters for particular field. +func Register(id uint8, p *SidhParams) { + if _, ok := sidhParams[id]; ok { + msg := fmt.Sprintf("sidh: Field with id %d already registered", id) + panic(msg) + } + sidhParams[id] = *p +} diff --git a/dh/sidh/internal/common/types.go b/dh/sidh/internal/common/types.go new file mode 100644 index 0000000..3d793c1 --- /dev/null +++ b/dh/sidh/internal/common/types.go @@ -0,0 +1,106 @@ +package common + +const ( + // corresponds to words in P751 + FpMaxWords = 12 + // corresponds to byte size of P751 SIDH private key for B + MaxSidhPrivateKeyBsz = 48 + // corresponds to byte size of P751 SIKE private key for B + MaxSikePrivateKeyBsz = MaxSidhPrivateKeyBsz + MaxMsgBsz + // corresponds to SIKE max length of 'n' (see 1.4 of SIKE spec in NIST PQC round 1) + MaxMsgBsz = 40 + // corresponds to byte size of shared secret generated by SIKEp751 + MaxSharedSecretBsz = 188 + // correponds to by size of the P751 public key + MaxPublicKeySz = 3 * FpMaxWords * 64 + // correponds to by size of the ciphertext produced by SIKE/P751 + MaxCiphertextBsz = MaxMsgBsz + MaxPublicKeySz +) + +// Id's correspond to bitlength of the prime field characteristic +// Currently Fp751 is the only one supported by this implementation +const ( + Fp503 uint8 = iota + Fp751 + Fp434 +) + +// Representation of an element of the base field F_p. +// +// No particular meaning is assigned to the representation -- it could represent +// an element in Montgomery form, or not. Tracking the meaning of the field +// element is left to higher types. +type Fp [FpMaxWords]uint64 + +// Represents an intermediate product of two elements of the base field F_p. +type FpX2 [2 * FpMaxWords]uint64 + +// Represents an element of the extended field Fp^2 = Fp(x+i) +type Fp2 struct { + A Fp + B Fp +} + +type DomainParams struct { + // P, Q and R=P-Q base points + AffineP, AffineQ, AffineR Fp2 + // Size of a compuatation strategy for x-torsion group + IsogenyStrategy []uint32 + // Max size of secret key for x-torsion group + SecretBitLen uint + // Max size of secret key for x-torsion group + SecretByteLen uint +} + +type SidhParams struct { + ID uint8 + // Bytelen of P + Bytelen int + // The public key size, in bytes. + PublicKeySize int + // The shared secret size, in bytes. + SharedSecretSize int + // 2- and 3-torsion group parameter definitions + A, B DomainParams + // Precomputed identity element in the Fp2 in Montgomery domain + OneFp2 Fp2 + // Precomputed 1/2 in the Fp2 in Montgomery domain + HalfFp2 Fp2 + // Length of SIKE secret message. Must be one of {24,32,40}, + // depending on size of prime field used (see [SIKE], 1.4 and 5.1) + MsgLen int + // Length of SIKE ephemeral KEM key (see [SIKE], 1.4 and 5.1) + KemSize int + // Byte size of ciphertext that KEM produces + CiphertextSize int + // Defines A,C constant for starting curve Cy^2 = x^3 + Ax^2 + x + InitCurve ProjectiveCurveParameters +} + +// Stores curve projective parameters equivalent to A/C. Meaning of the +// values depends on the context. When working with isogenies over +// subgroup that are powers of: +// * three then (A:C) ~ (A+2C:A-2C) +// * four then (A:C) ~ (A+2C: 4C) +// See Appendix A of SIKE for more details +type CurveCoefficientsEquiv struct { + A Fp2 + C Fp2 +} + +// A point on the projective line P^1(F_{p^2}). +// +// This represents a point on the Kummer line of a Montgomery curve. The +// curve is specified by a ProjectiveCurveParameters struct. +type ProjectivePoint struct { + X Fp2 + Z Fp2 +} + +// A point on the projective line P^1(F_{p^2}). +// +// This is used to work projectively with the curve coefficients. +type ProjectiveCurveParameters struct { + A Fp2 + C Fp2 +} diff --git a/dh/sidh/internal/common/utils.go b/dh/sidh/internal/common/utils.go new file mode 100644 index 0000000..e5ff4b3 --- /dev/null +++ b/dh/sidh/internal/common/utils.go @@ -0,0 +1,46 @@ +package common + +// Constant time select. +// if pick == 1 (out = in1) +// if pick == 0 (out = in2) +// else out is undefined. +func Cpick(pick int, out, in1, in2 []byte) { + var which = byte((int8(pick << 7)) >> 7) + for i := range out { + out[i] = (in1[i] & which) | (in2[i] & ^which) + } +} + +// Read 2*bytelen(p) bytes into the given ExtensionFieldElement. +// +// It is an error to call this function if the input byte slice is less than 2*bytelen(p) bytes long. +func BytesToFp2(fp2 *Fp2, input []byte, bytelen int) { + if len(input) < 2*bytelen { + panic("input byte slice too short") + } + + for i := 0; i < bytelen; i++ { + j := i / 8 + k := uint64(i % 8) + fp2.A[j] |= uint64(input[i]) << (8 * k) + fp2.B[j] |= uint64(input[i+bytelen]) << (8 * k) + } +} + +// Convert the input to wire format. +// +// The output byte slice must be at least 2*bytelen(p) bytes long. +func Fp2ToBytes(output []byte, fp2 *Fp2, bytelen int) { + if len(output) < 2*bytelen { + panic("output byte slice too short") + } + + // convert to bytes in little endian form + for i := 0; i < bytelen; i++ { + // set i = j*8 + k + tmp := i / 8 + k := uint64(i % 8) + output[i] = byte(fp2.A[tmp] >> (8 * k)) + output[i+bytelen] = byte(fp2.B[tmp] >> (8 * k)) + } +} diff --git a/dh/sidh/internal/isogeny/curve_ops.go b/dh/sidh/internal/isogeny/curve_ops.go deleted file mode 100644 index 9a9581d..0000000 --- a/dh/sidh/internal/isogeny/curve_ops.go +++ /dev/null @@ -1,440 +0,0 @@ -package internal - -type CurveOperations struct { - Params *SidhParams -} - -// Computes j-invariant for a curve y2=x3+A/Cx+x with A,C in F_(p^2). Result -// is returned in jBytes buffer, encoded in little-endian format. Caller -// provided jBytes buffer has to be big enough to j-invariant value. In case -// of SIDH, buffer size must be at least size of shared secret. -// Implementation corresponds to Algorithm 9 from SIKE. -func (c *CurveOperations) Jinvariant(cparams *ProjectiveCurveParameters, jBytes []byte) { - var j, t0, t1 Fp2Element - - op := c.Params.Op - op.Square(&j, &cparams.A) // j = A^2 - op.Square(&t1, &cparams.C) // t1 = C^2 - op.Add(&t0, &t1, &t1) // t0 = t1 + t1 - op.Sub(&t0, &j, &t0) // t0 = j - t0 - op.Sub(&t0, &t0, &t1) // t0 = t0 - t1 - op.Sub(&j, &t0, &t1) // t0 = t0 - t1 - op.Square(&t1, &t1) // t1 = t1^2 - op.Mul(&j, &j, &t1) // j = j * t1 - op.Add(&t0, &t0, &t0) // t0 = t0 + t0 - op.Add(&t0, &t0, &t0) // t0 = t0 + t0 - op.Square(&t1, &t0) // t1 = t0^2 - op.Mul(&t0, &t0, &t1) // t0 = t0 * t1 - op.Add(&t0, &t0, &t0) // t0 = t0 + t0 - op.Add(&t0, &t0, &t0) // t0 = t0 + t0 - op.Inv(&j, &j) // j = 1/j - op.Mul(&j, &t0, &j) // j = t0 * j - - c.Fp2ToBytes(jBytes, &j) -} - -// Given affine points x(P), x(Q) and x(Q-P) in a extension field F_{p^2}, function -// recorvers projective coordinate A of a curve. This is Algorithm 10 from SIKE. -func (c *CurveOperations) RecoverCoordinateA(curve *ProjectiveCurveParameters, xp, xq, xr *Fp2Element) { - var t0, t1 Fp2Element - - op := c.Params.Op - op.Add(&t1, xp, xq) // t1 = Xp + Xq - op.Mul(&t0, xp, xq) // t0 = Xp * Xq - op.Mul(&curve.A, xr, &t1) // A = X(q-p) * t1 - op.Add(&curve.A, &curve.A, &t0) // A = A + t0 - op.Mul(&t0, &t0, xr) // t0 = t0 * X(q-p) - op.Sub(&curve.A, &curve.A, &c.Params.OneFp2) // A = A - 1 - op.Add(&t0, &t0, &t0) // t0 = t0 + t0 - op.Add(&t1, &t1, xr) // t1 = t1 + X(q-p) - op.Add(&t0, &t0, &t0) // t0 = t0 + t0 - op.Square(&curve.A, &curve.A) // A = A^2 - op.Inv(&t0, &t0) // t0 = 1/t0 - op.Mul(&curve.A, &curve.A, &t0) // A = A * t0 - op.Sub(&curve.A, &curve.A, &t1) // A = A - t1 -} - -// Computes equivalence (A:C) ~ (A+2C : A-2C) -func (c *CurveOperations) CalcCurveParamsEquiv3(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv { - var coef CurveCoefficientsEquiv - var c2 Fp2Element - var op = c.Params.Op - - op.Add(&c2, &cparams.C, &cparams.C) - // A24p = A+2*C - op.Add(&coef.A, &cparams.A, &c2) - // A24m = A-2*C - op.Sub(&coef.C, &cparams.A, &c2) - return coef -} - -// Computes equivalence (A:C) ~ (A+2C : 4C) -func (c *CurveOperations) CalcCurveParamsEquiv4(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv { - var coefEq CurveCoefficientsEquiv - var op = c.Params.Op - - op.Add(&coefEq.C, &cparams.C, &cparams.C) - // A24p = A+2C - op.Add(&coefEq.A, &cparams.A, &coefEq.C) - // C24 = 4*C - op.Add(&coefEq.C, &coefEq.C, &coefEq.C) - return coefEq -} - -// Helper function for ScalarMul3Pt(). Returns A+2C / 4. -func (c *CurveOperations) CalcAplus2Over4(cparams *ProjectiveCurveParameters) (ret Fp2Element) { - var tmp Fp2Element - var op = c.Params.Op - - // 2C - op.Add(&tmp, &cparams.C, &cparams.C) - // A+2C - op.Add(&ret, &cparams.A, &tmp) - // 1/4C - op.Add(&tmp, &tmp, &tmp) - op.Inv(&tmp, &tmp) - // A+2C/4C - op.Mul(&ret, &ret, &tmp) - return -} - -// Recovers (A:C) curve parameters from projectively equivalent (A+2C:A-2C). -func (c *CurveOperations) RecoverCurveCoefficients3(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) { - var op = c.Params.Op - - op.Add(&cparams.A, &coefEq.A, &coefEq.C) - // cparams.A = 2*(A+2C+A-2C) = 4A - op.Add(&cparams.A, &cparams.A, &cparams.A) - // cparams.C = (A+2C-A+2C) = 4C - op.Sub(&cparams.C, &coefEq.A, &coefEq.C) - return -} - -// Recovers (A:C) curve parameters from projectively equivalent (A+2C:4C). -func (c *CurveOperations) RecoverCurveCoefficients4(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) { - var op = c.Params.Op - // cparams.C = (4C)*1/2=2C - op.Mul(&cparams.C, &coefEq.C, &c.Params.HalfFp2) - // cparams.A = A+2C - 2C = A - op.Sub(&cparams.A, &coefEq.A, &cparams.C) - // cparams.C = 2C * 1/2 = C - op.Mul(&cparams.C, &cparams.C, &c.Params.HalfFp2) - return -} - -// Combined coordinate doubling and differential addition. Takes projective points -// P,Q,Q-P and (A+2C)/4C curve E coefficient. Returns 2*P and P+Q calculated on E. -// Function is used only by RightToLeftLadder. Corresponds to Algorithm 5 of SIKE -func (c *CurveOperations) xDblAdd(P, Q, QmP *ProjectivePoint, a24 *Fp2Element) (dblP, PaQ ProjectivePoint) { - var t0, t1, t2 Fp2Element - var op = c.Params.Op - - xQmP, zQmP := &QmP.X, &QmP.Z - xPaQ, zPaQ := &PaQ.X, &PaQ.Z - x2P, z2P := &dblP.X, &dblP.Z - xP, zP := &P.X, &P.Z - xQ, zQ := &Q.X, &Q.Z - - op.Add(&t0, xP, zP) // t0 = Xp+Zp - op.Sub(&t1, xP, zP) // t1 = Xp-Zp - op.Square(x2P, &t0) // 2P.X = t0^2 - op.Sub(&t2, xQ, zQ) // t2 = Xq-Zq - op.Add(xPaQ, xQ, zQ) // Xp+q = Xq+Zq - op.Mul(&t0, &t0, &t2) // t0 = t0 * t2 - op.Mul(z2P, &t1, &t1) // 2P.Z = t1 * t1 - op.Mul(&t1, &t1, xPaQ) // t1 = t1 * Xp+q - op.Sub(&t2, x2P, z2P) // t2 = 2P.X - 2P.Z - op.Mul(x2P, x2P, z2P) // 2P.X = 2P.X * 2P.Z - op.Mul(xPaQ, a24, &t2) // Xp+q = A24 * t2 - op.Sub(zPaQ, &t0, &t1) // Zp+q = t0 - t1 - op.Add(z2P, xPaQ, z2P) // 2P.Z = Xp+q + 2P.Z - op.Add(xPaQ, &t0, &t1) // Xp+q = t0 + t1 - op.Mul(z2P, z2P, &t2) // 2P.Z = 2P.Z * t2 - op.Square(zPaQ, zPaQ) // Zp+q = Zp+q ^ 2 - op.Square(xPaQ, xPaQ) // Xp+q = Xp+q ^ 2 - op.Mul(zPaQ, xQmP, zPaQ) // Zp+q = Xq-p * Zp+q - op.Mul(xPaQ, zQmP, xPaQ) // Xp+q = Zq-p * Xp+q - return -} - -// Given the curve parameters, xP = x(P), computes xP = x([2^k]P) -// Safe to overlap xP, x2P. -func (c *CurveOperations) Pow2k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) { - var t0, t1 Fp2Element - var op = c.Params.Op - - x, z := &xP.X, &xP.Z - for i := uint32(0); i < k; i++ { - op.Sub(&t0, x, z) // t0 = Xp - Zp - op.Add(&t1, x, z) // t1 = Xp + Zp - op.Square(&t0, &t0) // t0 = t0 ^ 2 - op.Square(&t1, &t1) // t1 = t1 ^ 2 - op.Mul(z, ¶ms.C, &t0) // Z2p = C24 * t0 - op.Mul(x, z, &t1) // X2p = Z2p * t1 - op.Sub(&t1, &t1, &t0) // t1 = t1 - t0 - op.Mul(&t0, ¶ms.A, &t1) // t0 = A24+ * t1 - op.Add(z, z, &t0) // Z2p = Z2p + t0 - op.Mul(z, z, &t1) // Zp = Z2p * t1 - } -} - -// Given the curve parameters, xP = x(P), and k >= 0, compute xP = x([3^k]P). -// -// Safe to overlap xP, xR. -func (c *CurveOperations) Pow3k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) { - var t0, t1, t2, t3, t4, t5, t6 Fp2Element - var op = c.Params.Op - - x, z := &xP.X, &xP.Z - for i := uint32(0); i < k; i++ { - op.Sub(&t0, x, z) // t0 = Xp - Zp - op.Square(&t2, &t0) // t2 = t0^2 - op.Add(&t1, x, z) // t1 = Xp + Zp - op.Square(&t3, &t1) // t3 = t1^2 - op.Add(&t4, &t1, &t0) // t4 = t1 + t0 - op.Sub(&t0, &t1, &t0) // t0 = t1 - t0 - op.Square(&t1, &t4) // t1 = t4^2 - op.Sub(&t1, &t1, &t3) // t1 = t1 - t3 - op.Sub(&t1, &t1, &t2) // t1 = t1 - t2 - op.Mul(&t5, &t3, ¶ms.A) // t5 = t3 * A24+ - op.Mul(&t3, &t3, &t5) // t3 = t5 * t3 - op.Mul(&t6, &t2, ¶ms.C) // t6 = t2 * A24- - op.Mul(&t2, &t2, &t6) // t2 = t2 * t6 - op.Sub(&t3, &t2, &t3) // t3 = t2 - t3 - op.Sub(&t2, &t5, &t6) // t2 = t5 - t6 - op.Mul(&t1, &t2, &t1) // t1 = t2 * t1 - op.Add(&t2, &t3, &t1) // t2 = t3 + t1 - op.Square(&t2, &t2) // t2 = t2^2 - op.Mul(x, &t2, &t4) // X3p = t2 * t4 - op.Sub(&t1, &t3, &t1) // t1 = t3 - t1 - op.Square(&t1, &t1) // t1 = t1^2 - op.Mul(z, &t1, &t0) // Z3p = t1 * t0 - } -} - -// Set (y1, y2, y3) = (1/x1, 1/x2, 1/x3). -// -// All xi, yi must be distinct. -func (c *CurveOperations) Fp2Batch3Inv(x1, x2, x3, y1, y2, y3 *Fp2Element) { - var x1x2, t Fp2Element - var op = c.Params.Op - - op.Mul(&x1x2, x1, x2) // x1*x2 - op.Mul(&t, &x1x2, x3) // 1/(x1*x2*x3) - op.Inv(&t, &t) - op.Mul(y1, &t, x2) // 1/x1 - op.Mul(y1, y1, x3) - op.Mul(y2, &t, x1) // 1/x2 - op.Mul(y2, y2, x3) - op.Mul(y3, &t, &x1x2) // 1/x3 -} - -// ScalarMul3Pt is a right-to-left point multiplication that given the -// x-coordinate of P, Q and P-Q calculates the x-coordinate of R=Q+[scalar]P. -// nbits must be smaller or equal to len(scalar). -func (c *CurveOperations) ScalarMul3Pt(cparams *ProjectiveCurveParameters, P, Q, PmQ *ProjectivePoint, nbits uint, scalar []uint8) ProjectivePoint { - var R0, R2, R1 ProjectivePoint - var op = c.Params.Op - aPlus2Over4 := c.CalcAplus2Over4(cparams) - R1 = *P - R2 = *PmQ - R0 = *Q - - // Iterate over the bits of the scalar, bottom to top - prevBit := uint8(0) - for i := uint(0); i < nbits; i++ { - bit := (scalar[i>>3] >> (i & 7) & 1) - swap := prevBit ^ bit - prevBit = bit - op.CondSwap(&R1.X, &R1.Z, &R2.X, &R2.Z, swap) - R0, R2 = c.xDblAdd(&R0, &R2, &R1, &aPlus2Over4) - } - op.CondSwap(&R1.X, &R1.Z, &R2.X, &R2.Z, prevBit) - return R1 -} - -// Convert the input to wire format. -// -// The output byte slice must be at least 2*bytelen(p) bytes long. -func (c *CurveOperations) Fp2ToBytes(output []byte, fp2 *Fp2Element) { - if len(output) < 2*c.Params.Bytelen { - panic("output byte slice too short") - } - var a Fp2Element - c.Params.Op.FromMontgomery(fp2, &a) - - // convert to bytes in little endian form - for i := 0; i < c.Params.Bytelen; i++ { - // set i = j*8 + k - fp2 := i / 8 - k := uint64(i % 8) - output[i] = byte(a.A[fp2] >> (8 * k)) - output[i+c.Params.Bytelen] = byte(a.B[fp2] >> (8 * k)) - } -} - -// Read 2*bytelen(p) bytes into the given ExtensionFieldElement. -// -// It is an error to call this function if the input byte slice is less than 2*bytelen(p) bytes long. -func (c *CurveOperations) Fp2FromBytes(fp2 *Fp2Element, input []byte) { - if len(input) < 2*c.Params.Bytelen { - panic("input byte slice too short") - } - - for i := 0; i < c.Params.Bytelen; i++ { - j := i / 8 - k := uint64(i % 8) - fp2.A[j] |= uint64(input[i]) << (8 * k) - fp2.B[j] |= uint64(input[i+c.Params.Bytelen]) << (8 * k) - } - c.Params.Op.ToMontgomery(fp2) -} - -/* ------------------------------------------------------------------------- - Mechnisms used for isogeny calculations - -------------------------------------------------------------------------*/ - -// Constructs isogeny3 objects -func Newisogeny3(op FieldOps) Isogeny { - return &isogeny3{Field: op} -} - -// Constructs isogeny4 objects -func Newisogeny4(op FieldOps) Isogeny { - return &isogeny4{isogeny3: isogeny3{Field: op}} -} - -// Given a three-torsion point p = x(PB) on the curve E_(A:C), construct the -// three-isogeny phi : E_(A:C) -> E_(A:C)/ = E_(A':C'). -// -// Input: (XP_3: ZP_3), where P_3 has exact order 3 on E_A/C -// Output: * Curve coordinates (A' + 2C', A' - 2C') corresponding to E_A'/C' = A_E/C/ -// * Isogeny phi with constants in F_p^2 -func (phi *isogeny3) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv { - var t0, t1, t2, t3, t4 Fp2Element - var coefEq CurveCoefficientsEquiv - var K1, K2 = &phi.K1, &phi.K2 - - op := phi.Field - op.Sub(K1, &p.X, &p.Z) // K1 = XP3 - ZP3 - op.Square(&t0, K1) // t0 = K1^2 - op.Add(K2, &p.X, &p.Z) // K2 = XP3 + ZP3 - op.Square(&t1, K2) // t1 = K2^2 - op.Add(&t2, &t0, &t1) // t2 = t0 + t1 - op.Add(&t3, K1, K2) // t3 = K1 + K2 - op.Square(&t3, &t3) // t3 = t3^2 - op.Sub(&t3, &t3, &t2) // t3 = t3 - t2 - op.Add(&t2, &t1, &t3) // t2 = t1 + t3 - op.Add(&t3, &t3, &t0) // t3 = t3 + t0 - op.Add(&t4, &t3, &t0) // t4 = t3 + t0 - op.Add(&t4, &t4, &t4) // t4 = t4 + t4 - op.Add(&t4, &t1, &t4) // t4 = t1 + t4 - op.Mul(&coefEq.C, &t2, &t4) // A24m = t2 * t4 - op.Add(&t4, &t1, &t2) // t4 = t1 + t2 - op.Add(&t4, &t4, &t4) // t4 = t4 + t4 - op.Add(&t4, &t0, &t4) // t4 = t0 + t4 - op.Mul(&t4, &t3, &t4) // t4 = t3 * t4 - op.Sub(&t0, &t4, &coefEq.C) // t0 = t4 - A24m - op.Add(&coefEq.A, &coefEq.C, &t0) // A24p = A24m + t0 - return coefEq -} - -// Given a 3-isogeny phi and a point pB = x(PB), compute x(QB), the x-coordinate -// of the image QB = phi(PB) of PB under phi : E_(A:C) -> E_(A':C'). -// -// The output xQ = x(Q) is then a point on the curve E_(A':C'); the curve -// parameters are returned by the GenerateCurve function used to construct phi. -func (phi *isogeny3) EvaluatePoint(p *ProjectivePoint) ProjectivePoint { - var t0, t1, t2 Fp2Element - var q ProjectivePoint - var K1, K2 = &phi.K1, &phi.K2 - var px, pz = &p.X, &p.Z - - op := phi.Field - op.Add(&t0, px, pz) // t0 = XQ + ZQ - op.Sub(&t1, px, pz) // t1 = XQ - ZQ - op.Mul(&t0, K1, &t0) // t2 = K1 * t0 - op.Mul(&t1, K2, &t1) // t1 = K2 * t1 - op.Add(&t2, &t0, &t1) // t2 = t0 + t1 - op.Sub(&t0, &t1, &t0) // t0 = t1 - t0 - op.Square(&t2, &t2) // t2 = t2 ^ 2 - op.Square(&t0, &t0) // t0 = t0 ^ 2 - op.Mul(&q.X, px, &t2) // XQ'= XQ * t2 - op.Mul(&q.Z, pz, &t0) // ZQ'= ZQ * t0 - return q -} - -// Given a four-torsion point p = x(PB) on the curve E_(A:C), construct the -// four-isogeny phi : E_(A:C) -> E_(A:C)/ = E_(A':C'). -// -// Input: (XP_4: ZP_4), where P_4 has exact order 4 on E_A/C -// Output: * Curve coordinates (A' + 2C', 4C') corresponding to E_A'/C' = A_E/C/ -// * Isogeny phi with constants in F_p^2 -func (phi *isogeny4) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv { - var coefEq CurveCoefficientsEquiv - var xp4, zp4 = &p.X, &p.Z - var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3 - - op := phi.Field - op.Sub(K2, xp4, zp4) - op.Add(K3, xp4, zp4) - op.Square(K1, zp4) - op.Add(K1, K1, K1) - op.Square(&coefEq.C, K1) - op.Add(K1, K1, K1) - op.Square(&coefEq.A, xp4) - op.Add(&coefEq.A, &coefEq.A, &coefEq.A) - op.Square(&coefEq.A, &coefEq.A) - return coefEq -} - -// Given a 4-isogeny phi and a point xP = x(P), compute x(Q), the x-coordinate -// of the image Q = phi(P) of P under phi : E_(A:C) -> E_(A':C'). -// -// Input: Isogeny returned by GenerateCurve and point q=(Qx,Qz) from E0_A/C -// Output: Corresponding point q from E1_A'/C', where E1 is 4-isogenous to E0 -func (phi *isogeny4) EvaluatePoint(p *ProjectivePoint) ProjectivePoint { - var t0, t1 Fp2Element - var q = *p - var xq, zq = &q.X, &q.Z - var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3 - - op := phi.Field - op.Add(&t0, xq, zq) - op.Sub(&t1, xq, zq) - op.Mul(xq, &t0, K2) - op.Mul(zq, &t1, K3) - op.Mul(&t0, &t0, &t1) - op.Mul(&t0, &t0, K1) - op.Add(&t1, xq, zq) - op.Sub(zq, xq, zq) - op.Square(&t1, &t1) - op.Square(zq, zq) - op.Add(xq, &t0, &t1) - op.Sub(&t0, zq, &t0) - op.Mul(xq, xq, &t1) - op.Mul(zq, zq, &t0) - return q -} - -/* ------------------------------------------------------------------------- - Utils - -------------------------------------------------------------------------*/ -func (point *ProjectivePoint) ToAffine(c *CurveOperations) *Fp2Element { - var affine_x Fp2Element - c.Params.Op.Inv(&affine_x, &point.Z) - c.Params.Op.Mul(&affine_x, &affine_x, &point.X) - return &affine_x -} - -// Cleans data in fp -func (fp *Fp2Element) Zeroize() { - // Zeroizing in 2 seperated loops tells compiler to - // use fast runtime.memclr() - for i := range fp.A { - fp.A[i] = 0 - } - for i := range fp.B { - fp.B[i] = 0 - } -} diff --git a/dh/sidh/internal/isogeny/types.go b/dh/sidh/internal/isogeny/types.go deleted file mode 100644 index e0d22c4..0000000 --- a/dh/sidh/internal/isogeny/types.go +++ /dev/null @@ -1,145 +0,0 @@ -package internal - -const ( - FP_MAX_WORDS = 12 // Currently p751.NumWords -) - -// Representation of an element of the base field F_p. -// -// No particular meaning is assigned to the representation -- it could represent -// an element in Montgomery form, or not. Tracking the meaning of the field -// element is left to higher types. -type FpElement [FP_MAX_WORDS]uint64 - -// Represents an intermediate product of two elements of the base field F_p. -type FpElementX2 [2 * FP_MAX_WORDS]uint64 - -// Represents an element of the extended field Fp^2 = Fp(x+i) -type Fp2Element struct { - A FpElement - B FpElement -} - -type DomainParams struct { - // P, Q and R=P-Q base points - Affine_P, Affine_Q, Affine_R Fp2Element - // Size of a compuatation strategy for x-torsion group - IsogenyStrategy []uint32 - // Max size of secret key for x-torsion group - SecretBitLen uint - // Max size of secret key for x-torsion group - SecretByteLen uint -} - -type SidhParams struct { - Id uint8 - // Bytelen of P - Bytelen int - // The public key size, in bytes. - PublicKeySize int - // The shared secret size, in bytes. - SharedSecretSize uint - // 2- and 3-torsion group parameter definitions - A, B DomainParams - // Sample rate to obtain a value in [0,3^238] - SampleRate uint - // Precomputed identity element in the Fp2 in Montgomery domain - OneFp2 Fp2Element - // Precomputed 1/2 in the Fp2 in Montgomery domain - HalfFp2 Fp2Element - // Length of SIKE secret message. Must be one of {24,32,40}, - // depending on size of prime field used (see [SIKE], 1.4 and 5.1) - MsgLen uint - // Length of SIKE ephemeral KEM key (see [SIKE], 1.4 and 5.1) - KemSize uint - // Access to field arithmetic - Op FieldOps -} - -// Interface for working with isogenies. -type Isogeny interface { - // Given a torsion point on a curve computes isogenous curve. - // Returns curve coefficients (A:C), so that E_(A/C) = E_(A/C)/

, - // where P is a provided projective point. Sets also isogeny constants - // that are needed for isogeny evaluation. - GenerateCurve(*ProjectivePoint) CurveCoefficientsEquiv - // Evaluates isogeny at caller provided point. Requires isogeny curve constants - // to be earlier computed by GenerateCurve. - EvaluatePoint(*ProjectivePoint) ProjectivePoint -} - -// Stores curve projective parameters equivalent to A/C. Meaning of the -// values depends on the context. When working with isogenies over -// subgroup that are powers of: -// * three then (A:C) ~ (A+2C:A-2C) -// * four then (A:C) ~ (A+2C: 4C) -// See Appendix A of SIKE for more details -type CurveCoefficientsEquiv struct { - A Fp2Element - C Fp2Element -} - -// A point on the projective line P^1(F_{p^2}). -// -// This represents a point on the Kummer line of a Montgomery curve. The -// curve is specified by a ProjectiveCurveParameters struct. -type ProjectivePoint struct { - X Fp2Element - Z Fp2Element -} - -// A point on the projective line P^1(F_{p^2}). -// -// This is used to work projectively with the curve coefficients. -type ProjectiveCurveParameters struct { - A Fp2Element - C Fp2Element -} - -// Stores Isogeny 3 curve constants -type isogeny3 struct { - Field FieldOps - K1 Fp2Element - K2 Fp2Element -} - -// Stores Isogeny 4 curve constants -type isogeny4 struct { - isogeny3 - K3 Fp2Element -} - -type FieldOps interface { - // Set res = lhs + rhs. - // - // Allowed to overlap lhs or rhs with res. - Add(res, lhs, rhs *Fp2Element) - - // Set res = lhs - rhs. - // - // Allowed to overlap lhs or rhs with res. - Sub(res, lhs, rhs *Fp2Element) - - // Set res = lhs * rhs. - // - // Allowed to overlap lhs or rhs with res. - Mul(res, lhs, rhs *Fp2Element) - // Set res = x * x - // - // Allowed to overlap res with x. - Square(res, x *Fp2Element) - // Set res = 1/x - // - // Allowed to overlap res with x. - Inv(res, x *Fp2Element) - // In case choice == 1, performs following swap in constant time: - // xPx <-> xQx - // xPz <-> xQz - // Otherwise returns xPx, xPz, xQx, xQz unchanged - CondSwap(xPx, xPz, xQx, xQz *Fp2Element, choice uint8) - // Converts Fp2Element to Montgomery domain (x*R mod p) - ToMontgomery(x *Fp2Element) - // Converts 'a' in montgomery domain to element from Fp2Element - // and stores it in 'x' - FromMontgomery(x *Fp2Element, a *Fp2Element) -} diff --git a/dh/sidh/internal/p434/arith_amd64.s b/dh/sidh/internal/p434/arith_amd64.s new file mode 100644 index 0000000..74523ce --- /dev/null +++ b/dh/sidh/internal/p434/arith_amd64.s @@ -0,0 +1,1232 @@ +// +build amd64,!noasm + +#include "textflag.h" + +// p434 +#define P434_0 $0xFFFFFFFFFFFFFFFF +#define P434_3 $0xFDC1767AE2FFFFFF +#define P434_4 $0x7BC65C783158AEA3 +#define P434_5 $0x6CFC5FD681C52056 +#define P434_6 $0x0002341F27177344 + +// p434 x 2 +#define P434X2_0 $0xFFFFFFFFFFFFFFFE +#define P434X2_1 $0xFFFFFFFFFFFFFFFF +#define P434X2_3 $0xFB82ECF5C5FFFFFF +#define P434X2_4 $0xF78CB8F062B15D47 +#define P434X2_5 $0xD9F8BFAD038A40AC +#define P434X2_6 $0x0004683E4E2EE688 + +// Redefine P434p1Zeros +#define P434_P1_ZEROS 3 + +// Performs schoolbook multiplication of 128-bit with 256-bit +// number. Uses MULX, ADOX, ADCX instruction. +#define MULX128x256(IDX, M0, M1, T0, T1, T2, T3, T4, T5, T6) \ + XORQ AX, AX \ + MOVQ (IDX)(M0), DX \ + MULXQ M1+ 0(SB), T0, T1 \ // T0 <- C0 + MULXQ M1+ 8(SB), T4, T2 \ + MULXQ M1+16(SB), T5, T3 \ + ADOXQ T4, T1 \ // T1: interm1 + ADOXQ T5, T2 \ // T2: interm2 + \ + MULXQ M1+24(SB), T5, T4 \ + ADOXQ T5, T3 \ // T3: interm3 + ADOXQ AX, T4 \ // T4: interm4 + \ + XORQ AX, AX \ + MOVQ (IDX+8)(M0), DX \ + MULXQ M1+ 0(SB), T5, T6 \ + ADCXQ T5, T1 \ // T1 <- C1 + ADCXQ T6, T2 \ + \ + MULXQ M1+ 8(SB), T6, T5 \ + ADCXQ T5, T3 \ + ADOXQ T6, T2 \ // T2 <- C2 + \ + MULXQ M1+16(SB), T6, T5 \ + ADCXQ T5, T4 \ + ADOXQ T6, T3 \ // T3 <- C3 + \ + MULXQ M1+24(SB), T6, T5 \ + ADCXQ AX, T5 \ + ADOXQ T6, T4 \ // T4 <- C4 + ADOXQ AX, T5 // T5 <- C5 + +// Performs schoolbook multiplication of 64-bit with 256-bit +// number. Uses MULX and ADOX instructions. +// +// Uses registers: DX,AX +#define MULX64x256(IDX, M0, M1, T0, T1, T2, T3, T4, T5) \ + XORQ AX, AX \ + MOVQ (IDX)(M0), DX \ + MULXQ M1+ 0(SB), T0, T1 \ // T0 <- C0 + MULXQ M1+ 8(SB), T4, T2 \ + MULXQ M1+16(SB), T5, T3 \ + \ + ADOXQ T4, T1 \ // T1 <- C1 + ADOXQ T5, T2 \ // T2 <- C2 + \ + MULXQ M1+24(SB), T5, T4 \ + ADOXQ T5, T3 \ // T3 <- C3 + ADOXQ AX, T4 // T4 <- C4 + +// Performs schoolbook multiplication of two 192-bit numbers +// number. Uses MULX and ADOX instructions. +// +// Uses registers: DX,AX +#define MULX192(IM0,M0,IM1,M1,ID,MDST,T0,T1,T2,T3,T4,T5,T6) \ + MOVQ (0+IM0)(M0), DX \ + MULXQ (0+IM1)(M1), T1, T0 \ // T0:T1 = A0*B0 + MOVQ T1,(ID+0)(MDST) \ // MDST0 + MULXQ (IM1+ 8)(M1), T2, T1 \ // T1:T2 = A0*B1 + XORQ AX, AX \ + ADOXQ T2, T0 \ + MULXQ (IM1+16)(M1),T3, T2 \ // T2:T3 = A0*B2 + ADOXQ T3, T1 \ + \ + MOVQ (IM0+8)(M0), DX \ + MULXQ (IM1+0)(M1), T4, T3 \ // T3:T4 = A1*B0 + ADOXQ AX, T2 \ + XORQ AX, AX \ + \ + MULXQ (IM1+8)(M1), T6, T5 \ // T6:T7 = A1*B1 + ADOXQ T0, T4 \ + MOVQ T4,(ID+8)(MDST) \ // MDST1 + ADCXQ T6, T3 \ + \ + MULXQ (IM1+16)(M1),T0, T6 \ // T6:T0 = A1*B2 + ADOXQ T1, T3 \ + ADCXQ T0, T5 \ + ADCXQ AX, T6 \ + ADOXQ T2, T5 \ + \ + MOVQ (IM0+16)(M0),DX \ + MULXQ (IM1+ 0)(M1), T0, T1 \ // T1:T0 = A2*B0 + ADOXQ AX, T6 \ + XORQ AX, AX \ + \ + MULXQ (IM1+ 8)(M1), T2, T4 \ // T4:T2 = A2*B1 + ADOXQ T3, T0 \ + MOVQ T0, (ID+16)(MDST) \ // MDST2 + ADCXQ T5, T1 \ + \ + MULXQ (IM1+16)(M1),T3, T0 \ // T0:T3 = A2*B2 + ADCXQ T6, T4 \ + ADCXQ AX, T0 \ + ADOXQ T2, T1 \ + ADOXQ T4, T3 \ + ADOXQ AX, T0 \ + MOVQ T1, (ID+24)(MDST) \ // MDST3 + MOVQ T3, (ID+32)(MDST) \ // MDST4 + MOVQ T0, (ID+40)(MDST) // MDST5 + +// Performs schoolbook multiplication of 2 256-bit numbers. Uses +// MULX instruction. Result is stored in 256 bits pointed by $DST. +// +// Uses registers: DX,AX +#define MULX256(IM0,M0,IM1,M1,ID,MDST,T0,T1,T2,T3,T4,T5,T6,T7,T8,T9) \ + MOVQ (IM0+0)(M0), DX \ + MULXQ (IM1+0)(M1), T1, T0 \ // A0*B[0-3] + MOVQ T1, (ID+0)(MDST) \ + MULXQ (IM1+8)(M1), T2, T1 \ + XORQ AX, AX \ + ADOXQ T2, T0 \ + MULXQ (IM1+16)(M1),T3, T2 \ + ADOXQ T3, T1 \ + MULXQ (IM1+24)(M1),T4, T3 \ + ADOXQ T4, T2 \ + \ + MOVQ (IM0+8)(M0), DX \ + MULXQ (IM1+0)(M1), T4, T5 \ // A1*B[0-3] + ADOXQ AX, T3 \ + XORQ AX, AX \ + MULXQ (IM1+8)(M1), T7, T6 \ + ADOXQ T0, T4 \ + MOVQ T4, (ID+8)(MDST) \ + ADCXQ T7, T5 \ + MULXQ (IM1+16)(M1),T8, T7 \ + ADCXQ T8, T6 \ + ADOXQ T1, T5 \ + MULXQ (IM1+24)(M1),T9, T8 \ + ADCXQ T9, T7 \ + ADCXQ AX, T8 \ + ADOXQ T2, T6 \ + \ + MOVQ (IM0+16)(M0),DX \ // A2*B[0-3] + MULXQ (IM1+ 0)(M1), T0, T1 \ + ADOXQ T3, T7 \ + ADOXQ AX, T8 \ + XORQ AX, AX \ + MULXQ (IM1+8)(M1), T3, T2 \ + ADOXQ T5, T0 \ + MOVQ T0, (ID+16)(MDST) \ + ADCXQ T3, T1 \ + MULXQ (IM1+16)(M1),T4, T3 \ + ADCXQ T4, T2 \ + ADOXQ T6, T1 \ + MULXQ (IM1+24)(M1),T9, T4 \ + ADCXQ T9, T3 \ + ADCXQ AX, T4 \ + \ + ADOXQ T7, T2 \ + ADOXQ T8, T3 \ + ADOXQ AX, T4 \ + \ + MOVQ (IM0+24)(M0),DX \ + MULXQ (IM1+ 0)(M1), T0, T5\ // A3*B[0-3] + XORQ AX, AX \ + MULXQ (IM1+ 8)(M1), T7, T6\ + ADCXQ T7, T5 \ + ADOXQ T0, T1 \ + MULXQ (IM1+16)(M1), T8, T7 \ + ADCXQ T8, T6 \ + ADOXQ T5, T2 \ + MULXQ (IM1+24)(M1), T9, T8 \ + ADCXQ T9, T7 \ + ADCXQ AX, T8 \ + ADOXQ T6, T3 \ + ADOXQ T7, T4 \ + ADOXQ AX, T8 \ + MOVQ T1, (ID+24)(MDST) \ + MOVQ T2, (ID+32)(MDST) \ + MOVQ T3, (ID+40)(MDST) \ + MOVQ T4, (ID+48)(MDST) \ + MOVQ T8, (ID+56)(MDST) + +// Performs schoolbook multiplication of 64-bit with 256-bit +// number. +// +// Uses registers: DX, AX +#define MUL64x256(IDX,M0,M1,C0,C1,C2,C3,C4,T0) \ + MOVQ (IDX)(M0), T0 \ + \ + XORQ C2, C2 \ + MOVQ M1+0(SB), AX \ + MULQ T0 \ + MOVQ AX, C0 \ + MOVQ DX, C1 \ + \ + XORQ C3, C3 \ + MOVQ M1+8(SB), AX \ + MULQ T0 \ + ADDQ AX, C1 \ + ADCQ DX, C2 \ + \ + XORQ C4, C4 \ + MOVQ M1+16(SB), AX \ + MULQ T0 \ + ADDQ AX, C2 \ + ADCQ DX, C3 \ + \ + MOVQ M1+24(SB), AX \ + MULQ T0 \ + ADDQ AX, C3 \ + ADCQ DX, C4 + +// Performs schoolbook multiplication of 128-bit with 256-bit +// number. Destroys RAX and RDX +// +// Uses registers: DX, AX +#define MUL128x256(IDX,M0,M1,C0,C1,C2,C3,C4,C5,T0,T1) \ + \ // A0 x B0 + MOVQ (IDX+0)(M0), T0 \ + MOVQ M1+0(SB), AX \ + MULQ T0 \ + XORQ C2, C2 \ + MOVQ AX, C0 \ + MOVQ DX, C1 \ + \ // A0 x B1 + MOVQ M1+8(SB), AX \ + MULQ T0 \ + XORQ C3, C3 \ + ADDQ AX, C1 \ + ADCQ DX, C2 \ + \ // A1 x B0 + MOVQ (IDX+8)(M0), T1 \ + MOVQ M1+0(SB), AX \ + MULQ T1 \ + ADDQ AX, C1 \ + ADCQ DX, C2 \ + ADCQ $0, C3 \ + \ // A0 x B2 + XORQ C4, C4 \ + MOVQ M1+16(SB), AX \ + MULQ T0 \ + ADDQ AX, C2 \ + ADCQ DX, C3 \ + ADCQ $0, C4 \ + \ // A1 x B1 + MOVQ M1+8(SB), AX \ + MULQ T1 \ + ADDQ AX, C2 \ + ADCQ DX, C3 \ + ADCQ $0, C4 \ + \ // A0 x B3 + MOVQ M1+24(SB), AX \ + MULQ T0 \ + XORQ C5, C5 \ + ADDQ AX, C3 \ + ADCQ DX, C4 \ + ADCQ $0, C5 \ + \ // A1 x B2 + MOVQ M1+16(SB), AX \ + MULQ T1 \ + ADDQ AX, C3 \ + ADCQ DX, C4 \ + ADCQ $0, C5 \ + \ // A1 x B3 + MOVQ M1+24(SB), AX \ + MULQ T1 \ + ADDQ AX, C4 \ + ADCQ DX, C5 + +#define REDC_COMMON(MUL01, MUL23, MUL45, MUL67) \ + MUL01 \ + XORQ CX, CX \ + ADDQ 0x18(DI), R8 \ + ADCQ 0x20(DI), R9 \ + ADCQ 0x28(DI), R10 \ + ADCQ 0x30(DI), R11 \ + ADCQ 0x38(DI), R12 \ + ADCQ 0x40(DI), R13 \ + ADCQ 0x48(DI), CX \ + MOVQ R8, 0x18(DI) \ + MOVQ R9, 0x20(DI) \ + MOVQ R10, 0x28(DI) \ + MOVQ R11, 0x30(DI) \ + MOVQ R12, 0x38(DI) \ + MOVQ R13, 0x40(DI) \ + MOVQ CX, 0x48(DI) \ + MOVQ 0x50(DI), R8 \ + MOVQ 0x58(DI), R9 \ + MOVQ 0x60(DI), R10 \ + MOVQ 0x68(DI), R11 \ + ADCQ $0, R8 \ + ADCQ $0, R9 \ + ADCQ $0, R10 \ + ADCQ $0, R11 \ + MOVQ R8, 0x50(DI) \ + MOVQ R9, 0x58(DI) \ + MOVQ R10, 0x60(DI) \ + MOVQ R11, 0x68(DI) \ + \ + MUL23 \ + XORQ CX, CX \ + ADDQ 0x28(DI), R8 \ + ADCQ 0x30(DI), R9 \ + ADCQ 0x38(DI), R10 \ + ADCQ 0x40(DI), R11 \ + ADCQ 0x48(DI), R12 \ + ADCQ 0x50(DI), R13 \ + ADCQ 0x58(DI), CX \ + MOVQ R8, 0x28(DI) \ + MOVQ R9, 0x30(DI) \ + MOVQ R10, 0x38(DI) \ + MOVQ R11, 0x40(DI) \ + MOVQ R12, 0x48(DI) \ + MOVQ R13, 0x50(DI) \ + MOVQ CX, 0x58(DI) \ + MOVQ 0x60(DI), R8 \ + MOVQ 0x68(DI), R9 \ + ADCQ $0, R8 \ + ADCQ $0, R9 \ + MOVQ R8, 0x60(DI) \ + MOVQ R9, 0x68(DI) \ + \ + MUL45 \ + XORQ CX, CX \ + ADDQ 0x38(DI), R8 \ + ADCQ 0x40(DI), R9 \ + ADCQ 0x48(DI), R10 \ + ADCQ 0x50(DI), R11 \ + ADCQ 0x58(DI), R12 \ + ADCQ 0x60(DI), R13 \ + ADCQ 0x68(DI), CX \ + MOVQ R8, 0x0(SI) \ // OUT0 + MOVQ R9, 0x8(SI) \ // OUT1 + MOVQ R10, 0x48(DI) \ + MOVQ R11, 0x50(DI) \ + MOVQ R12, 0x58(DI) \ + MOVQ R13, 0x60(DI) \ + MOVQ CX, 0x68(DI) \ + \ + MUL67 \ + ADDQ 0x48(DI), R8 \ + ADCQ 0x50(DI), R9 \ + ADCQ 0x58(DI), R10 \ + ADCQ 0x60(DI), R11 \ + ADCQ 0x68(DI), R12 \ + MOVQ R8, 0x10(SI) \ // OUT2 + MOVQ R9, 0x18(SI) \ // OUT3 + MOVQ R10, 0x20(SI) \ // OUT4 + MOVQ R11, 0x28(SI) \ // OUT5 + MOVQ R12, 0x30(SI) // OUT6 + +TEXT ·cswapP434(SB),NOSPLIT,$0-17 + + MOVQ x+0(FP), DI + MOVQ y+8(FP), SI + MOVB choice+16(FP), AL // AL = 0 or 1 + MOVBLZX AL, AX // AX = 0 or 1 + NEGQ AX // AX = 0x00..00 or 0xff..ff +#ifndef CSWAP_BLOCK +#define CSWAP_BLOCK(idx) \ + MOVQ (idx*8)(DI), BX \ // BX = x[idx] + MOVQ (idx*8)(SI), CX \ // CX = y[idx] + MOVQ CX, DX \ // DX = y[idx] + XORQ BX, DX \ // DX = y[idx] ^ x[idx] + ANDQ AX, DX \ // DX = (y[idx] ^ x[idx]) & mask + XORQ DX, BX \ // BX = (y[idx] ^ x[idx]) & mask) ^ x[idx] = x[idx] or y[idx] + XORQ DX, CX \ // CX = (y[idx] ^ x[idx]) & mask) ^ y[idx] = y[idx] or x[idx] + MOVQ BX, (idx*8)(DI) \ + MOVQ CX, (idx*8)(SI) +#endif + CSWAP_BLOCK(0) + CSWAP_BLOCK(1) + CSWAP_BLOCK(2) + CSWAP_BLOCK(3) + CSWAP_BLOCK(4) + CSWAP_BLOCK(5) + CSWAP_BLOCK(6) +#ifdef CSWAP_BLOCK +#undef CSWAP_BLOCK +#endif + RET + +TEXT ·addP434(SB),NOSPLIT,$0-24 + MOVQ z+0(FP), DX + MOVQ x+8(FP), DI + MOVQ y+16(FP), SI + + // Used later to calculate a mask + XORQ CX, CX + + // [R8-R14]: z = x + y + MOVQ ( 0)(DI), R8; ADDQ ( 0)(SI), R8 + MOVQ ( 8)(DI), R9; ADCQ ( 8)(SI), R9 + MOVQ (16)(DI), R10; ADCQ (16)(SI), R10 + MOVQ (24)(DI), R11; ADCQ (24)(SI), R11 + MOVQ (32)(DI), R12; ADCQ (32)(SI), R12 + MOVQ (40)(DI), R13; ADCQ (40)(SI), R13 + MOVQ (48)(DI), R14; ADCQ (48)(SI), R14 + + XORQ DI, DI + + MOVQ P434X2_0, AX; SUBQ AX, R8 + MOVQ P434X2_1, AX; SBBQ AX, R9 + SBBQ AX, R10 + MOVQ P434X2_3, AX; SBBQ AX, R11 + MOVQ P434X2_4, AX; SBBQ AX, R12 + MOVQ P434X2_5, AX; SBBQ AX, R13 + MOVQ P434X2_6, AX; SBBQ AX, R14 + + // mask + SBBQ $0, CX + + // if z<0 add P434x2 back + MOVQ P434X2_0, R15; ANDQ CX, R15; + MOVQ P434X2_1, AX; ANDQ CX, AX; + + ADDQ R8, R15; MOVQ R15, ( 0)(DX) + ADCQ AX, R9; MOVQ R9, ( 8)(DX) + ADCQ AX, R10; MOVQ R10, (16)(DX) + + ADCQ $0, DI + MOVQ P434X2_3, R15; ANDQ CX, R15; + MOVQ P434X2_4, R8; ANDQ CX, R8; + MOVQ P434X2_5, R9; ANDQ CX, R9; + MOVQ P434X2_6, R10; ANDQ CX, R10; + BTQ $0, DI + + ADCQ R11, R15; MOVQ R15, (24)(DX) + ADCQ R12, R8; MOVQ R8, (32)(DX) + ADCQ R13, R9; MOVQ R9, (40)(DX) + ADCQ R14, R10; MOVQ R10, (48)(DX) + + RET + +TEXT ·adlP434(SB),NOSPLIT,$0-24 + MOVQ z+0(FP), DX + MOVQ x+8(FP), DI + MOVQ y+16(FP),SI + + MOVQ ( 0)(DI), R8 + ADDQ ( 0)(SI), R8 + MOVQ ( 8)(DI), R9 + ADCQ ( 8)(SI), R9 + MOVQ (16)(DI), R10 + ADCQ (16)(SI), R10 + MOVQ (24)(DI), R11 + ADCQ (24)(SI), R11 + MOVQ (32)(DI), R12 + ADCQ (32)(SI), R12 + MOVQ (40)(DI), R13 + ADCQ (40)(SI), R13 + MOVQ (48)(DI), R14 + ADCQ (48)(SI), R14 + MOVQ (56)(DI), R15 + ADCQ (56)(SI), R15 + MOVQ (64)(DI), AX + ADCQ (64)(SI), AX + MOVQ (72)(DI), BX + ADCQ (72)(SI), BX + MOVQ (80)(DI), CX + ADCQ (80)(SI), CX + + MOVQ R8, ( 0)(DX) + MOVQ R9, ( 8)(DX) + MOVQ R10,(16)(DX) + MOVQ R11,(24)(DX) + MOVQ R12,(32)(DX) + MOVQ R13,(40)(DX) + MOVQ R14,(48)(DX) + MOVQ R15,(56)(DX) + MOVQ AX, (64)(DX) + MOVQ BX, (72)(DX) + MOVQ CX, (80)(DX) + + MOVQ (88)(DI), R8 + ADCQ (88)(SI), R8 + MOVQ (96)(DI), R9 + ADCQ (96)(SI), R9 + MOVQ (104)(DI), R10 + ADCQ (104)(SI), R10 + + MOVQ R8, (88)(DX) + MOVQ R9, (96)(DX) + MOVQ R10,(104)(DX) + RET + +TEXT ·subP434(SB),NOSPLIT,$0-24 + MOVQ z+0(FP), DX + MOVQ x+8(FP), DI + MOVQ y+16(FP), SI + + // Used later to calculate a mask + XORQ CX, CX + + MOVQ ( 0)(DI), R8; SUBQ ( 0)(SI), R8 + MOVQ ( 8)(DI), R9; SBBQ ( 8)(SI), R9 + MOVQ (16)(DI), R10; SBBQ (16)(SI), R10 + MOVQ (24)(DI), R11; SBBQ (24)(SI), R11 + MOVQ (32)(DI), R12; SBBQ (32)(SI), R12 + MOVQ (40)(DI), R13; SBBQ (40)(SI), R13 + MOVQ (48)(DI), R14; SBBQ (48)(SI), R14 + + // mask + SBBQ $0, CX + XORQ R15, R15 + + // if z<0 add p434x2 back + MOVQ P434X2_0, DI; ANDQ CX, DI + MOVQ P434X2_1, SI; ANDQ CX, SI + MOVQ P434X2_3, AX; ANDQ CX, AX + + ADDQ DI, R8; MOVQ R8, ( 0)(DX) + ADCQ SI, R9; MOVQ R9, ( 8)(DX) + ADCQ SI, R10; MOVQ R10, (16)(DX) + ADCQ AX, R11; MOVQ R11, (24)(DX) + ADCQ $0, R15 + + MOVQ P434X2_4, R8; ANDQ CX, R8; + MOVQ P434X2_5, R9; ANDQ CX, R9; + MOVQ P434X2_6, R10; ANDQ CX, R10 + + BTQ $0, R15 + + ADCQ R8, R12; MOVQ R12, (32)(DX) + ADCQ R9, R13; MOVQ R13, (40)(DX) + ADCQ R10, R14; MOVQ R14, (48)(DX) + RET + +TEXT ·sulP434(SB),NOSPLIT,$0-24 + MOVQ z+0(FP), DX + MOVQ x+8(FP), DI + MOVQ y+16(FP), SI + + // Used later to store result of 0-borrow + XORQ CX, CX + + // SUBC for first 10 limbs + MOVQ ( 0)(DI), R8; SUBQ ( 0)(SI), R8 + MOVQ ( 8)(DI), R9; SBBQ ( 8)(SI), R9 + MOVQ (16)(DI), R10; SBBQ (16)(SI), R10 + MOVQ (24)(DI), R11; SBBQ (24)(SI), R11 + MOVQ (32)(DI), R12; SBBQ (32)(SI), R12 + MOVQ (40)(DI), R13; SBBQ (40)(SI), R13 + MOVQ (48)(DI), R14; SBBQ (48)(SI), R14 + MOVQ (56)(DI), R15; SBBQ (56)(SI), R15 + MOVQ (64)(DI), AX; SBBQ (64)(SI), AX + MOVQ (72)(DI), BX; SBBQ (72)(SI), BX + + MOVQ R8, ( 0)(DX) + MOVQ R9, ( 8)(DX) + MOVQ R10, (16)(DX) + MOVQ R11, (24)(DX) + MOVQ R12, (32)(DX) + MOVQ R13, (40)(DX) + MOVQ R14, (48)(DX) + MOVQ R15, (56)(DX) + MOVQ AX, (64)(DX) + MOVQ BX, (72)(DX) + + // SUBC for last 4 limbs + MOVQ ( 80)(DI), R8; SBBQ ( 80)(SI), R8 + MOVQ ( 88)(DI), R9; SBBQ ( 88)(SI), R9 + MOVQ ( 96)(DI), R10; SBBQ ( 96)(SI), R10 + MOVQ (104)(DI), R11; SBBQ (104)(SI), R11 + + // Store carry flag + SBBQ $0, CX + + MOVQ R8, ( 80)(DX) + MOVQ R9, ( 88)(DX) + MOVQ R10, ( 96)(DX) + MOVQ R11, (104)(DX) + + // Load p into registers: + MOVQ P434_0, R8; ANDQ CX, R8 + // P434_{1,2} = P434_0, so reuse R8 + MOVQ P434_3, R9; ANDQ CX, R9 + MOVQ P434_4, R10; ANDQ CX, R10 + MOVQ P434_5, R11; ANDQ CX, R11 + MOVQ P434_6, R12; ANDQ CX, R12 + + MOVQ (56 )(DX), AX; ADDQ R8, AX; MOVQ AX, (56 )(DX) + MOVQ (56+ 8)(DX), AX; ADCQ R8, AX; MOVQ AX, (56+ 8)(DX) + MOVQ (56+16)(DX), AX; ADCQ R8, AX; MOVQ AX, (56+16)(DX) + MOVQ (56+24)(DX), AX; ADCQ R9, AX; MOVQ AX, (56+24)(DX) + MOVQ (56+32)(DX), AX; ADCQ R10, AX; MOVQ AX, (56+32)(DX) + MOVQ (56+40)(DX), AX; ADCQ R11, AX; MOVQ AX, (56+40)(DX) + MOVQ (56+48)(DX), AX; ADCQ R12, AX; MOVQ AX, (56+48)(DX) + + RET + +TEXT ·modP434(SB),NOSPLIT,$0-8 + MOVQ x+0(FP), DI + + // Zero AX for later use: + XORQ AX, AX + + // Set x <- x - p + MOVQ P434_0, R8 + SUBQ R8, ( 0)(DI) + // P434_{1,2} = P434_0, so reuse R8 + MOVQ P434_3, R9 + SBBQ R8, ( 8)(DI) + SBBQ R8, (16)(DI) + MOVQ P434_4, R10 + SBBQ R9, (24)(DI) + MOVQ P434_5, R11 + SBBQ R10, (32)(DI) + MOVQ P434_6, R12 + SBBQ R11, (40)(DI) + SBBQ R12, (48)(DI) + + // save carry + SBBQ $0, AX + + // Conditionally add p to x if x-p < 0 + ANDQ AX, R8 + ANDQ AX, R9 + ANDQ AX, R10 + ANDQ AX, R11 + ANDQ AX, R12 + + ADDQ R8, ( 0)(DI) + ADCQ R8, ( 8)(DI) + ADCQ R8, (16)(DI) + ADCQ R9, (24)(DI) + ADCQ R10,(32)(DI) + ADCQ R11,(40)(DI) + ADCQ R12,(48)(DI) + RET + +// 434-bit multiplication using Karatsuba (one level), +// schoolbook (one level). +TEXT ·mulP434(SB),NOSPLIT,$112-24 + MOVQ z+0(FP), CX + MOVQ x+8(FP), DI + MOVQ y+16(FP), SI + + // Check wether to use optimized implementation + CMPB ·HasADXandBMI2(SB), $1 + JE mul_with_mulx_adcx_adox + + // rcx[0-3] <- AH+AL + XORQ AX, AX + MOVQ 0x20(DI), R8 + MOVQ 0x28(DI), R9 + MOVQ 0x30(DI), R10 + XORQ R11, R11 + ADDQ 0x0(DI), R8 + ADCQ 0x8(DI), R9 + ADCQ 0x10(DI), R10 + ADCQ 0x18(DI), R11 + // store AH+AL mask + SBBQ $0, AX + MOVQ AX, 0x40(SP) + // store AH+AL in 0-0x18(rcx) + MOVQ R8, 0x0(CX) + MOVQ R9, 0x8(CX) + MOVQ R10, 0x10(CX) + MOVQ R11, 0x18(CX) + + // r12-r15 <- BH+BL + XORQ DX, DX + MOVQ 0x20(SI), R12 + MOVQ 0x28(SI), R13 + MOVQ 0x30(SI), R14 + XORQ R15, R15 + ADDQ 0x0(SI), R12 + ADCQ 0x8(SI), R13 + ADCQ 0x10(SI), R14 + ADCQ 0x18(SI), R15 + SBBQ $0, DX + + // store BH+BL mask + MOVQ DX, 0x48(SP) + + // (rsp[0-0x38]) <- (AH+AL)*(BH+BL) + MOVQ (CX), AX + MULQ R12 + MOVQ AX, (SP) + MOVQ DX, R8 + + XORQ R9, R9 + MOVQ (CX), AX + MULQ R13 + ADDQ AX, R8 + ADCQ DX, R9 + + XORQ R10, R10 + MOVQ 0x8(CX), AX + MULQ R12 + ADDQ AX, R8 + MOVQ R8, 0x8(SP) + ADCQ DX, R9 + ADCQ $0, R10 + + XORQ R8, R8 + MOVQ (CX), AX + MULQ R14 + ADDQ AX, R9 + ADCQ DX, R10 + ADCQ $0, R8 + + MOVQ 0x10(CX), AX + MULQ R12 + ADDQ AX, R9 + ADCQ DX, R10 + ADCQ $0, R8 + + MOVQ 0x8(CX), AX + MULQ R13 + ADDQ AX, R9 + MOVQ R9, 0x10(SP) + ADCQ DX, R10 + ADCQ $0, R8 + + XORQ R9, R9 + MOVQ (CX),AX + MULQ R15 + ADDQ AX, R10 + ADCQ DX, R8 + ADCQ $0, R9 + + MOVQ 0x18(CX), AX + MULQ R12 + ADDQ AX, R10 + ADCQ DX, R8 + ADCQ $0, R9 + + MOVQ 0x8(CX), AX + MULQ R14 + ADDQ AX, R10 + ADCQ DX, R8 + ADCQ $0, R9 + + MOVQ 0x10(CX), AX + MULQ R13 + ADDQ AX, R10 + MOVQ R10, 0x18(SP) + ADCQ DX, R8 + ADCQ $0, R9 + + XORQ R10, R10 + MOVQ 0x8(CX), AX + MULQ R15 + ADDQ AX, R8 + ADCQ DX, R9 + ADCQ $0, R10 + + MOVQ 0x18(CX), AX + MULQ R13 + ADDQ AX, R8 + ADCQ DX, R9 + ADCQ $0, R10 + + MOVQ 0x10(CX), AX + MULQ R14 + ADDQ AX, R8 + MOVQ R8, 0x20(SP) + ADCQ DX, R9 + ADCQ $0, R10 + + XORQ R11, R11 + MOVQ 0x10(CX), AX + MULQ R15 + ADDQ AX, R9 + ADCQ DX, R10 + ADCQ $0, R11 + + MOVQ 0x18(CX), AX + MULQ R14 + ADDQ AX, R9 + MOVQ R9, 0x28(SP) + ADCQ DX, R10 + ADCQ $0, R11 + + MOVQ 0x18(CX), AX + MULQ R15 + ADDQ AX, R10 + MOVQ R10, 0x30(SP) + ADCQ DX, R11 + MOVQ R11,0x38(SP) + + // r12-r15 <- masked (BH + BL) + MOVQ 0x40(SP), AX + ANDQ AX, R12 + ANDQ AX, R13 + ANDQ AX, R14 + ANDQ AX, R15 + + // r8-r11 <- masked (AH + AL) + MOVQ 0x48(SP), AX + MOVQ 0x00(CX), R8 + ANDQ AX, R8 + MOVQ 0x08(CX), R9 + ANDQ AX, R9 + MOVQ 0x10(CX), R10 + ANDQ AX, R10 + MOVQ 0x18(CX), R11 + ANDQ AX, R11 + + // r12-r15 <- masked (AH + AL) + masked (BH + BL) + ADDQ R8, R12 + ADCQ R9, R13 + ADCQ R10, R14 + ADCQ R11, R15 + + // rsp[0x20-0x38] <- (AH+AL) x (BH+BL) high + MOVQ 0x20(SP), AX + ADDQ AX, R12 + MOVQ 0x28(SP), AX + ADCQ AX, R13 + MOVQ 0x30(SP), AX + ADCQ AX, R14 + MOVQ 0x38(SP), AX + ADCQ AX, R15 + MOVQ R12, 0x50(SP) + MOVQ R13, 0x58(SP) + MOVQ R14, 0x60(SP) + MOVQ R15, 0x68(SP) + + // [rcx] <- CL = AL x BL + MOVQ (DI), R11 + MOVQ (SI), AX + MULQ R11 + XORQ R9, R9 + MOVQ AX, (CX) + MOVQ DX, R8 + + MOVQ 0x10(DI), R14 + MOVQ 0x8(SI), AX + MULQ R11 + XORQ R10, R10 + ADDQ AX, R8 + ADCQ DX, R9 + + MOVQ 0x8(DI), R12 + MOVQ (SI), AX + MULQ R12 + ADDQ AX, R8 + MOVQ R8, 0x8(CX) + ADCQ DX, R9 + ADCQ $0, R10 + + XORQ R8, R8 + MOVQ 0x10(SI), AX + MULQ R11 + ADDQ AX, R9 + ADCQ DX, R10 + ADCQ $0, R8 + + MOVQ (SI), R13 + MOVQ R14, AX + MULQ R13 + ADDQ AX, R9 + ADCQ DX, R10 + ADCQ $0, R8 + + MOVQ 0x8(SI), AX + MULQ R12 + ADDQ AX, R9 + MOVQ R9, 0x10(CX) + ADCQ DX, R10 + ADCQ $0, R8 + + XORQ R9, R9 + MOVQ 0x18(SI), AX + MULQ R11 + MOVQ 0x18(DI), R15 + ADDQ AX, R10 + ADCQ DX, R8 + ADCQ $0, R9 + + MOVQ R15, AX + MULQ R13 + ADDQ AX, R10 + ADCQ DX, R8 + ADCQ $0, R9 + + MOVQ 0x10(SI), AX + MULQ R12 + ADDQ AX, R10 + ADCQ DX, R8 + ADCQ $0, R9 + + MOVQ 0x8(SI), AX + MULQ R14 + ADDQ AX, R10 + MOVQ R10, 0x18(CX) + ADCQ DX, R8 + ADCQ $0, R9 + + XORQ R10, R10 + MOVQ 0x18(SI), AX + MULQ R12 + ADDQ AX, R8 + ADCQ DX, R9 + ADCQ $0, R10 + + MOVQ 0x8(SI), AX + MULQ R15 + ADDQ AX, R8 + ADCQ DX, R9 + ADCQ $0, R10 + + MOVQ 0x10(SI), AX + MULQ R14 + ADDQ AX, R8 + MOVQ R8, 0x20(CX) + ADCQ DX, R9 + ADCQ $0, R10 + + XORQ R8, R8 + MOVQ 0x18(SI), AX + MULQ R14 + ADDQ AX, R9 + ADCQ DX, R10 + ADCQ $0, R8 + + MOVQ 0x10(SI), AX + MULQ R15 + ADDQ AX, R9 + MOVQ R9, 0x28(CX) + ADCQ DX, R10 + ADCQ $0, R8 + + MOVQ 0x18(SI), AX + MULQ R15 + ADDQ AX, R10 + MOVQ R10, 0x30(CX) + ADCQ DX, R8 + MOVQ R8, 0x38(CX) + + // rcx[0x40-0x68] <- AH*BH + // multiplies 2 192-bit numbers A,B + MOVQ 0x20(DI), R11 + MOVQ 0x20(SI), AX + MULQ R11 + XORQ R9, R9 + MOVQ AX, 0x40(CX) + MOVQ DX, R8 + + MOVQ 0x30(DI), R14 + MOVQ 0x28(SI), AX + MULQ R11 + XORQ R10, R10 + ADDQ AX, R8 + ADCQ DX, R9 + + MOVQ 0x28(DI), R12 + MOVQ 0x20(SI), AX + MULQ R12 + ADDQ AX, R8 + MOVQ R8, 0x48(CX) + ADCQ DX, R9 + ADCQ $0, R10 + + XORQ R8, R8 + MOVQ 0x30(SI), AX + MULQ R11 + ADDQ AX, R9 + ADCQ DX, R10 + ADCQ $0, R8 + + MOVQ 0x20(SI), R13 + MOVQ R14, AX + MULQ R13 + ADDQ AX, R9 + ADCQ DX, R10 + ADCQ $0, R8 + + MOVQ 0x28(SI), AX + MULQ R12 + ADDQ AX, R9 + MOVQ R9, 0x50(CX) + ADCQ DX, R10 + ADCQ $0, R8 + + MOVQ 0x30(SI), AX + MULQ R12 + XORQ R12, R12 + ADDQ AX, R10 + ADCQ DX, R8 + ADCQ $0, R12 + + MOVQ 0x28(SI), AX + MULQ R14 + ADDQ AX, R10 + ADCQ DX, R8 + ADCQ $0, R12 + MOVQ R10, 0x58(CX) + + MOVQ 0x30(SI), AX + MULQ R14 + ADDQ AX, R8 + ADCQ $0, R12 + MOVQ R8, 0x60(CX) + + ADDQ R12, DX + + // [r8-r15] <- (AH+AL)x(BH+BL) - ALxBL + MOVQ 0x0(SP), R8 + SUBQ 0x0(CX), R8 + MOVQ 0x8(SP), R9 + SBBQ 0x8(CX), R9 + MOVQ 0x10(SP), R10 + SBBQ 0x10(CX), R10 + MOVQ 0x18(SP), R11 + SBBQ 0x18(CX), R11 + MOVQ 0x50(SP), R12 + SBBQ 0x20(CX), R12 + MOVQ 0x58(SP), R13 + SBBQ 0x28(CX), R13 + MOVQ 0x60(SP), R14 + SBBQ 0x30(CX), R14 + MOVQ 0x68(SP), R15 + SBBQ 0x38(CX), R15 + + // [r8-r15] <- (AH+AL) x (BH+BL) - ALxBL - AHxBH + MOVQ 0x40(CX), AX + SUBQ AX, R8 + MOVQ 0x48(CX), AX + SBBQ AX, R9 + MOVQ 0x50(CX), AX + SBBQ AX, R10 + MOVQ 0x58(CX), AX + SBBQ AX, R11 + MOVQ 0x60(CX), AX + SBBQ AX, R12 + SBBQ DX, R13 + SBBQ $0, R14 + SBBQ $0, R15 + + // Final result + ADDQ 0x20(CX), R8 + MOVQ R8, 0x20(CX) // OUT4 + ADCQ 0x28(CX), R9 + MOVQ R9, 0x28(CX) // OUT5 + ADCQ 0x30(CX), R10 + MOVQ R10, 0x30(CX) // OUT6 + ADCQ 0x38(CX), R11 + MOVQ R11, 0x38(CX) // OUT7 + ADCQ 0x40(CX), R12 + MOVQ R12, 0x40(CX) // OUT8 + ADCQ 0x48(CX), R13 + MOVQ R13, 0x48(CX) // OUT9 + ADCQ 0x50(CX), R14 + MOVQ R14, 0x50(CX) // OUT10 + ADCQ 0x58(CX), R15 + MOVQ R15, 0x58(CX) // OUT11 + MOVQ 0x60(CX), R12 + ADCQ $0, R12 + MOVQ R12, 0x60(CX) // OUT12 + ADCQ $0, DX + MOVQ DX, 0x68(CX) // OUT13 + RET + +mul_with_mulx_adcx_adox: + // Mul implementation for CPUs supporting two independent carry chain + // (ADOX/ADCX) instructions and carry-less MULX multiplier + XORQ AX, AX + MOVQ 0x0(DI), R8 + MOVQ 0x8(DI), R9 + MOVQ 0x10(DI), R10 + MOVQ 0x18(DI), R11 + + MOVQ BP, 0x70(SP) + + ADDQ 0x20(DI), R8 + ADCQ 0x28(DI), R9 + ADCQ 0x30(DI), R10 + ADCQ $0, R11 + SBBQ $0, AX + MOVQ R8, 0x0(SP) + MOVQ R9, 0x8(SP) + MOVQ R10, 0x10(SP) + MOVQ R11, 0x18(SP) + + // r12-r15 <- BH + BL, rbx <- mask + XORQ BX, BX + MOVQ 0x0(SI), R12 + MOVQ 0x8(SI), R13 + MOVQ 0x10(SI), R14 + MOVQ 0x18(SI), R15 + ADDQ 0x20(SI), R12 + ADCQ 0x28(SI), R13 + ADCQ 0x30(SI), R14 + ADCQ $0, R15 + SBBQ $0, BX + MOVQ R12, 0x20(SP) + MOVQ R13, 0x28(SP) + MOVQ R14, 0x30(SP) + MOVQ R15, 0x38(SP) + + // r12-r15 <- masked (BH + BL) + ANDQ AX, R12 + ANDQ AX, R13 + ANDQ AX, R14 + ANDQ AX, R15 + + // r8-r11 <- masked (AH + AL) + ANDQ BX, R8 + ANDQ BX, R9 + ANDQ BX, R10 + ANDQ BX, R11 + + // r8-r11 <- masked (AH + AL) + masked (BH + BL) + ADDQ R12, R8 + ADCQ R13, R9 + ADCQ R14, R10 + ADCQ R15, R11 + MOVQ R8, 0x40(SP) + MOVQ R9, 0x48(SP) + MOVQ R10, 0x50(SP) + MOVQ R11, 0x58(SP) + + // [rsp] <- CM = (AH+AL) x (BH+BL) + MULX256(0,SP,32,SP,0,SP,R8,R9,R10,R11,R12,R13,R14,R15,BX,BP) + // [rcx] <- CL = AL x BL (Result c0-c3) + MULX256(0,DI,0,SI,0,CX,R8,R9,R10,R11,R12,R13,R14,R15,BX,BP) + // [rcx+64] <- CH = AH x BH + MULX192(32,DI,32,SI,64,CX,R8,R9,R10,R11,R12,R13,R14) + + // r8-r11 <- (AH+AL) x (BH+BL), final step + MOVQ 0x40(SP), R8 + MOVQ 0x48(SP), R9 + MOVQ 0x50(SP), R10 + MOVQ 0x58(SP), R11 + + MOVQ 0x20(SP), AX + ADDQ AX, R8 + MOVQ 0x28(SP), AX + ADCQ AX, R9 + MOVQ 0x30(SP), AX + ADCQ AX, R10 + MOVQ 0x38(SP), AX + ADCQ AX, R11 + + // [rsp], x3-x5 <- (AH+AL) x (BH+BL) - ALxBL + MOVQ 0x0(SP), R12 + MOVQ 0x8(SP), R13 + MOVQ 0x10(SP), R14 + MOVQ 0x18(SP), R15 + SUBQ 0x0(CX), R12 + SBBQ 0x8(CX), R13 + SBBQ 0x10(CX), R14 + SBBQ 0x18(CX), R15 + SBBQ 0x20(CX), R8 + SBBQ 0x28(CX), R9 + SBBQ 0x30(CX), R10 + SBBQ 0x38(CX), R11 + + // r8-r15 <- (AH+AL) x (BH+BL) - ALxBL - AHxBH + SUBQ 0x40(CX), R12 + SBBQ 0x48(CX), R13 + SBBQ 0x50(CX), R14 + SBBQ 0x58(CX), R15 + SBBQ 0x60(CX), R8 + SBBQ 0x68(CX), R9 + SBBQ $0, R10 + SBBQ $0, R11 + + ADDQ 0x20(CX), R12 + MOVQ R12, 0x20(CX) // OUT4 + ADCQ 0x28(CX), R13 + MOVQ R13, 0x28(CX) // OUT5 + ADCQ 0x30(CX), R14 + MOVQ R14, 0x30(CX) // OUT6 + ADCQ 0x38(CX), R15 + MOVQ R15, 0x38(CX) // OUT7 + ADCQ 0x40(CX), R8 + MOVQ R8, 0x40(CX) // OUT8 + ADCQ 0x48(CX), R9 + MOVQ R9, 0x48(CX) // OUT9 + ADCQ 0x50(CX), R10 + MOVQ R10, 0x50(CX) // OUT10 + ADCQ 0x58(CX), R11 + MOVQ R11, 0x58(CX) // OUT11 + MOVQ 0x60(CX), R12 + ADCQ $0, R12 + MOVQ R12, 0x60(CX) // OUT12 + MOVQ 0x68(CX), R13 + ADCQ $0, R13 + MOVQ R13, 0x68(CX) // OUT13 + + MOVQ 0x70(SP), BP + RET + +TEXT ·rdcP434(SB),$0-16 + MOVQ z+0(FP), SI + MOVQ x+8(FP), DI + CMPB ·HasADXandBMI2(SB), $1 + JE redc_bdw +#define MUL01 MUL128x256( 0,DI,·P434p1+(8*P434_P1_ZEROS),R8,R9,R10,R11,R12,R13,R14,CX) +#define MUL23 MUL128x256(16,DI,·P434p1+(8*P434_P1_ZEROS),R8,R9,R10,R11,R12,R13,R14,CX) +#define MUL45 MUL128x256(32,DI,·P434p1+(8*P434_P1_ZEROS),R8,R9,R10,R11,R12,R13,R14,CX) +#define MUL67 MUL64x256(48,DI,·P434p1+(8*P434_P1_ZEROS),R8,R9,R10,R11,R12,R13) + REDC_COMMON(MUL01, MUL23, MUL45, MUL67) +#undef MUL01 +#undef MUL23 +#undef MUL45 +#undef MUL67 + RET + +// 434-bit montgomery reduction Uses MULX/ADOX/ADCX instructions +// available on Broadwell micro-architectures and newer. +redc_bdw: +#define MULX01 MULX128x256( 0,DI,·P434p1+(8*P434_P1_ZEROS),R8,R9,R10,R11,R12,R13,CX) +#define MULX23 MULX128x256(16,DI,·P434p1+(8*P434_P1_ZEROS),R8,R9,R10,R11,R12,R13,CX) +#define MULX45 MULX128x256(32,DI,·P434p1+(8*P434_P1_ZEROS),R8,R9,R10,R11,R12,R13,CX) +#define MULX67 MULX64x256(48,DI,·P434p1+(8*P434_P1_ZEROS),R8,R9,R10,R11,R12,R13) + REDC_COMMON(MULX01, MULX23, MULX45, MULX67) +#undef MULX01 +#undef MULX23 +#undef MULX45 +#undef MULX67 + RET diff --git a/dh/sidh/internal/p434/arith_amd64_test.go b/dh/sidh/internal/p434/arith_amd64_test.go new file mode 100644 index 0000000..ec8a001 --- /dev/null +++ b/dh/sidh/internal/p434/arith_amd64_test.go @@ -0,0 +1,96 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +// +build amd64,!noasm + +package p434 + +import ( + "reflect" + "testing" + "testing/quick" + + "github.com/henrydcase/nobs/sidh/internal/common" + "golang.org/x/sys/cpu" +) + +type OptimFlag uint + +const ( + // Indicates that optimisation which uses MUL instruction should be used + kUse_MUL OptimFlag = 1 << 0 + // Indicates that optimisation which uses MULX, ADOX and ADCX instructions should be used + kUse_MULXandADxX = 1 << 1 +) + +func resetCpuFeatures() { + HasADXandBMI2 = cpu.X86.HasBMI2 && cpu.X86.HasADX +} + +// Utility function used for testing Mul implementations. Tests caller provided +// mulFunc against mul() +func testMul(t *testing.T, f1, f2 OptimFlag) { + doMulTest := func(multiplier, multiplicant common.Fp) bool { + defer resetCpuFeatures() + var resMulRef, resMulOptim common.FpX2 + + // Compute multiplier*multiplicant with first implementation + HasADXandBMI2 = (kUse_MULXandADxX & f1) == kUse_MULXandADxX + mulP434(&resMulOptim, &multiplier, &multiplicant) + + // Compute multiplier*multiplicant with second implementation + HasADXandBMI2 = (kUse_MULXandADxX & f2) == kUse_MULXandADxX + mulP434(&resMulRef, &multiplier, &multiplicant) + + // Compare results + return reflect.DeepEqual(resMulRef, resMulOptim) + } + + if err := quick.Check(doMulTest, quickCheckConfig); err != nil { + t.Error(err) + } +} + +// Utility function used for testing REDC implementations. Tests caller provided +// redcFunc against redc() +func testRedc(t *testing.T, f1, f2 OptimFlag) { + doRedcTest := func(aRR common.FpX2) bool { + defer resetCpuFeatures() + var resRedcF1, resRedcF2 common.Fp + var aRRcpy = aRR + + // Compute redc with first implementation + HasADXandBMI2 = (kUse_MULXandADxX & f1) == kUse_MULXandADxX + rdcP434(&resRedcF1, &aRR) + + // Compute redc with second implementation + HasADXandBMI2 = (kUse_MULXandADxX & f2) == kUse_MULXandADxX + rdcP434(&resRedcF2, &aRRcpy) + + // Compare results + return reflect.DeepEqual(resRedcF2, resRedcF1) + } + + if err := quick.Check(doRedcTest, quickCheckConfig); err != nil { + t.Error(err) + } +} + +// Ensures correctness of implementation of mul operation which uses MULX and ADOX/ADCX +func TestMulWithMULXADxX(t *testing.T) { + defer resetCpuFeatures() + if !HasADXandBMI2 { + t.Skip("MULX, ADCX and ADOX not supported by the platform") + } + testMul(t, kUse_MULXandADxX, kUse_MUL) +} + +// Ensures correctness of Montgomery reduction implementation which uses MULX +// and ADCX/ADOX. +func TestRedcWithMULXADxX(t *testing.T) { + defer resetCpuFeatures() + if !HasADXandBMI2 { + t.Skip("MULX, ADCX and ADOX not supported by the platform") + } + testRedc(t, kUse_MULXandADxX, kUse_MUL) +} diff --git a/dh/sidh/internal/p434/arith_decl.go b/dh/sidh/internal/p434/arith_decl.go new file mode 100644 index 0000000..7c9c415 --- /dev/null +++ b/dh/sidh/internal/p434/arith_decl.go @@ -0,0 +1,45 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +// +build amd64,!noasm + +package p434 + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// If choice = 0, leave x,y unchanged. If choice = 1, set x,y = y,x. +// If choice is neither 0 nor 1 then behaviour is undefined. +// This function executes in constant time. +//go:noescape +func cswapP434(x, y *Fp, choice uint8) + +// Compute z = x + y (mod p). +//go:noescape +func addP434(z, x, y *Fp) + +// Compute z = x - y (mod p). +//go:noescape +func subP434(z, x, y *Fp) + +// Compute z = x + y, without reducing mod p. +//go:noescape +func adlP434(z, x, y *FpX2) + +// Compute z = x - y, without reducing mod p. +//go:noescape +func sulP434(z, x, y *FpX2) + +// Reduce a field element in [0, 2*p) to one in [0,p). +//go:noescape +func modP434(x *Fp) + +// Computes z = x * y. +//go:noescape +func mulP434(z *FpX2, x, y *Fp) + +// Computes the Montgomery reduction z = x R^{-1} (mod 2*p). On return value +// of x may be changed. z=x not allowed. +//go:noescape +func rdcP434(z *Fp, x *FpX2) diff --git a/dh/sidh/internal/p434/arith_generic.go b/dh/sidh/internal/p434/arith_generic.go new file mode 100644 index 0000000..68be920 --- /dev/null +++ b/dh/sidh/internal/p434/arith_generic.go @@ -0,0 +1,192 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +// +build noasm,arm64 !amd64 + +package p434 + +import ( + "math/bits" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Compute z = x + y (mod p). +func addP434(z, x, y *common.Fp) { + var carry uint64 + + // z=x+y % P434 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Add64(x[i], y[i], carry) + } + + // z = z - P434x2 + carry = 0 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Sub64(z[i], P434x2[i], carry) + } + + // if z<0 add P434x2 back + mask := uint64(0 - carry) + carry = 0 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Add64(z[i], P434x2[i]&mask, carry) + } +} + +// Compute z = x - y (mod p). +func subP434(z, x, y *common.Fp) { + var borrow uint64 + + for i := 0; i < FpWords; i++ { + z[i], borrow = bits.Sub64(x[i], y[i], borrow) + } + + mask := uint64(0 - borrow) + borrow = 0 + + for i := 0; i < FpWords; i++ { + z[i], borrow = bits.Add64(z[i], P434x2[i]&mask, borrow) + } +} + +// Conditionally swaps bits in x and y in constant time. +// mask indicates bits to be swapped (set bits are swapped) +// For details see "Hackers Delight, 2.20" +// +// Implementation doesn't actually depend on a prime field. +func cswapP434(x, y *common.Fp, mask uint8) { + var tmp, mask64 uint64 + + mask64 = 0 - uint64(mask) + for i := 0; i < FpWords; i++ { + tmp = mask64 & (x[i] ^ y[i]) + x[i] = tmp ^ x[i] + y[i] = tmp ^ y[i] + } +} + +// Perform Montgomery reduction: set z = x R^{-1} (mod 2*p) +// with R=2^(FpWords*64). Destroys the input value. +func rdcP434(z *common.Fp, x *common.FpX2) { + var carry, t, u, v uint64 + var hi, lo uint64 + var count int + + count = P434p1Zeros + + for i := 0; i < FpWords; i++ { + for j := 0; j < i; j++ { + if j < (i - count + 1) { + hi, lo = bits.Mul64(z[j], P434p1[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + } + v, carry = bits.Add64(v, x[i], 0) + u, carry = bits.Add64(u, 0, carry) + t += carry + + z[i] = v + v = u + u = t + t = 0 + } + + for i := FpWords; i < 2*FpWords-1; i++ { + if count > 0 { + count-- + } + for j := i - FpWords + 1; j < FpWords; j++ { + if j < (FpWords - count) { + hi, lo = bits.Mul64(z[j], P434p1[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + } + v, carry = bits.Add64(v, x[i], 0) + u, carry = bits.Add64(u, 0, carry) + + t += carry + z[i-FpWords] = v + v = u + u = t + t = 0 + } + v, _ = bits.Add64(v, x[2*FpWords-1], 0) + z[FpWords-1] = v +} + +// Compute z = x * y. +func mulP434(z *common.FpX2, x, y *common.Fp) { + var u, v, t uint64 + var hi, lo uint64 + var carry uint64 + + for i := uint64(0); i < FpWords; i++ { + for j := uint64(0); j <= i; j++ { + hi, lo = bits.Mul64(x[j], y[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + z[i] = v + v = u + u = t + t = 0 + } + + for i := FpWords; i < (2*FpWords)-1; i++ { + for j := i - FpWords + 1; j < FpWords; j++ { + hi, lo = bits.Mul64(x[j], y[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + z[i] = v + v = u + u = t + t = 0 + } + z[2*FpWords-1] = v +} + +// Compute z = x + y, without reducing mod p. +func adlP434(z, x, y *common.FpX2) { + var carry uint64 + for i := 0; i < 2*FpWords; i++ { + z[i], carry = bits.Add64(x[i], y[i], carry) + } +} + +// Reduce a field element in [0, 2*p) to one in [0,p). +func modP434(x *common.Fp) { + var borrow, mask uint64 + for i := 0; i < FpWords; i++ { + x[i], borrow = bits.Sub64(x[i], P434[i], borrow) + } + + // Sets all bits if borrow = 1 + mask = 0 - borrow + borrow = 0 + for i := 0; i < FpWords; i++ { + x[i], borrow = bits.Add64(x[i], P434[i]&mask, borrow) + } +} + +// Compute z = x - y, without reducing mod p. +func sulP434(z, x, y *common.FpX2) { + var borrow, mask uint64 + for i := 0; i < 2*FpWords; i++ { + z[i], borrow = bits.Sub64(x[i], y[i], borrow) + } + + // Sets all bits if borrow = 1 + mask = 0 - borrow + borrow = 0 + for i := FpWords; i < 2*FpWords; i++ { + z[i], borrow = bits.Add64(z[i], P434[i-FpWords]&mask, borrow) + } +} diff --git a/dh/sidh/internal/p434/arith_test.go b/dh/sidh/internal/p434/arith_test.go new file mode 100644 index 0000000..c9f1a6a --- /dev/null +++ b/dh/sidh/internal/p434/arith_test.go @@ -0,0 +1,101 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p434 + +import ( + "testing" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Package-level storage for this field element is intended to deter +// compiler optimizations. +var ( + benchmarkFp common.Fp + benchmarkFpX2 common.FpX2 + bench_x = common.Fp{17026702066521327207, 5108203422050077993, 10225396685796065916, 11153620995215874678, 6531160855165088358, 15302925148404145445, 1248821577836769963, 9789766903037985294, 7493111552032041328, 10838999828319306046, 18103257655515297935, 27403304611634} + bench_y = common.Fp{4227467157325093378, 10699492810770426363, 13500940151395637365, 12966403950118934952, 16517692605450415877, 13647111148905630666, 14223628886152717087, 7167843152346903316, 15855377759596736571, 4300673881383687338, 6635288001920617779, 30486099554235} + bench_z = common.FpX2{1595347748594595712, 10854920567160033970, 16877102267020034574, 12435724995376660096, 3757940912203224231, 8251999420280413600, 3648859773438820227, 17622716832674727914, 11029567000887241528, 11216190007549447055, 17606662790980286987, 4720707159513626555, 12887743598335030915, 14954645239176589309, 14178817688915225254, 1191346797768989683, 12629157932334713723, 6348851952904485603, 16444232588597434895, 7809979927681678066, 14642637672942531613, 3092657597757640067, 10160361564485285723, 240071237} +) + +func TestFpCswap(t *testing.T) { + var one = common.Fp{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + var two = common.Fp{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} + + var x = one + var y = two + + cswapP434(&x, &y, 0) + for i := 0; i < FpWords; i++ { + if (x[i] != one[i]) || (y[i] != two[i]) { + t.Error("Found", x, "expected", two) + } + } + + cswapP434(&x, &y, 1) + for i := 0; i < FpWords; i++ { + if (x[i] != two[i]) || (y[i] != one[i]) { + t.Error("Found", x, "expected", two) + } + } +} + +// Benchmarking for field arithmetic +func BenchmarkMul(b *testing.B) { + for n := 0; n < b.N; n++ { + mulP434(&benchmarkFpX2, &bench_x, &bench_y) + } +} + +func BenchmarkRdc(b *testing.B) { + z := bench_z + + // This benchmark actually computes garbage, because + // rdcP434 mangles its input, but since it's + // constant-time that shouldn't matter for the benchmarks. + for n := 0; n < b.N; n++ { + rdcP434(&benchmarkFp, &z) + } +} + +func BenchmarkAdd(b *testing.B) { + for n := 0; n < b.N; n++ { + addP434(&benchmarkFp, &bench_x, &bench_y) + } +} + +func BenchmarkSub(b *testing.B) { + for n := 0; n < b.N; n++ { + subP434(&benchmarkFp, &bench_x, &bench_y) + } +} + +func BenchmarkCswap(b *testing.B) { + x, y := bench_x, bench_y + for n := 0; n < b.N; n++ { + cswapP434(&x, &y, 1) + cswapP434(&x, &y, 0) + } +} + +func BenchmarkMod(b *testing.B) { + x := bench_x + for n := 0; n < b.N; n++ { + modP434(&x) + } +} + +func BenchmarkX2AddLazy(b *testing.B) { + x, y, z := bench_z, bench_z, bench_z + for n := 0; n < b.N; n++ { + adlP434(&x, &y, &z) + } +} + +func BenchmarkX2SubLazy(b *testing.B) { + x, y, z := bench_z, bench_z, bench_z + for n := 0; n < b.N; n++ { + sulP434(&x, &y, &z) + } +} diff --git a/dh/sidh/internal/p434/core.go b/dh/sidh/internal/p434/core.go new file mode 100644 index 0000000..1e5c3a2 --- /dev/null +++ b/dh/sidh/internal/p434/core.go @@ -0,0 +1,282 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p434 + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// ----------------------------------------------------------------------------- +// Functions for traversing isogeny trees acoording to strategy. Key type 'A' is +// + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreePublicKeyA(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny4 + + cparam := CalcCurveParamsEquiv4(curve) + strat := params.A.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow2k(xR, &cparam, 2*k) + i += int(k) + } + cparam = phi.GenerateCurve(xR) + + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + *phiP = phi.EvaluatePoint(phiP) + *phiQ = phi.EvaluatePoint(phiQ) + *phiR = phi.EvaluatePoint(phiR) + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR needed +// for public key generation. +func traverseTreeSharedKeyA(curve *ProjectiveCurveParameters, xR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny4 + + cparam := CalcCurveParamsEquiv4(curve) + strat := params.A.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow2k(xR, &cparam, 2*k) + i += int(k) + } + cparam = phi.GenerateCurve(xR) + + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreePublicKeyB(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny3 + + cparam := CalcCurveParamsEquiv3(curve) + strat := params.B.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow3k(xR, &cparam, k) + i += int(k) + } + + cparam = phi.GenerateCurve(xR) + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + *phiP = phi.EvaluatePoint(phiP) + *phiQ = phi.EvaluatePoint(phiQ) + *phiR = phi.EvaluatePoint(phiR) + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreeSharedKeyB(curve *ProjectiveCurveParameters, xR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny3 + + cparam := CalcCurveParamsEquiv3(curve) + strat := params.B.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow3k(xR, &cparam, k) + i += int(k) + } + + cparam = phi.GenerateCurve(xR) + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Generate a public key in the 2-torsion group. Public key is a set +// of three x-coordinates: xP,xQ,x(P-Q), where P,Q are points on E_a(Fp2) +func PublicKeyGenA(pub3Pt *[3]Fp2, prvBytes []byte) { + var xPA, xQA, xRA ProjectivePoint + var xPB, xQB, xRB, xR ProjectivePoint + var invZP, invZQ, invZR Fp2 + var phi isogeny4 + + // Load points for A + xPA = ProjectivePoint{X: params.A.AffineP, Z: params.OneFp2} + xQA = ProjectivePoint{X: params.A.AffineQ, Z: params.OneFp2} + xRA = ProjectivePoint{X: params.A.AffineR, Z: params.OneFp2} + + // Load points for B + xRB = ProjectivePoint{X: params.B.AffineR, Z: params.OneFp2} + xQB = ProjectivePoint{X: params.B.AffineQ, Z: params.OneFp2} + xPB = ProjectivePoint{X: params.B.AffineP, Z: params.OneFp2} + + // Find isogeny kernel + xR = ScalarMul3Pt(¶ms.InitCurve, &xPA, &xQA, &xRA, params.A.SecretBitLen, prvBytes) + traverseTreePublicKeyA(¶ms.InitCurve, &xR, &xPB, &xQB, &xRB) + + // Secret isogeny + phi.GenerateCurve(&xR) + xPA = phi.EvaluatePoint(&xPB) + xQA = phi.EvaluatePoint(&xQB) + xRA = phi.EvaluatePoint(&xRB) + Fp2Batch3Inv(&xPA.Z, &xQA.Z, &xRA.Z, &invZP, &invZQ, &invZR) + + mul(&pub3Pt[0], &xPA.X, &invZP) + mul(&pub3Pt[1], &xQA.X, &invZQ) + mul(&pub3Pt[2], &xRA.X, &invZR) +} + +// Generate a public key in the 2-torsion group. Public key is a set +// of three x-coordinates: xP,xQ,x(P-Q), where P,Q are points on E_a(Fp2) +func PublicKeyGenB(pub3Pt *[3]Fp2, prvBytes []byte) { + var xPB, xQB, xRB, xR ProjectivePoint + var xPA, xQA, xRA ProjectivePoint + var invZP, invZQ, invZR Fp2 + var phi isogeny3 + + // Load points for B + xRB = ProjectivePoint{X: params.B.AffineR, Z: params.OneFp2} + xQB = ProjectivePoint{X: params.B.AffineQ, Z: params.OneFp2} + xPB = ProjectivePoint{X: params.B.AffineP, Z: params.OneFp2} + + // Load points for A + xPA = ProjectivePoint{X: params.A.AffineP, Z: params.OneFp2} + xQA = ProjectivePoint{X: params.A.AffineQ, Z: params.OneFp2} + xRA = ProjectivePoint{X: params.A.AffineR, Z: params.OneFp2} + + // Find isogeny kernel + xR = ScalarMul3Pt(¶ms.InitCurve, &xPB, &xQB, &xRB, params.B.SecretBitLen, prvBytes) + traverseTreePublicKeyB(¶ms.InitCurve, &xR, &xPA, &xQA, &xRA) + + phi.GenerateCurve(&xR) + xPB = phi.EvaluatePoint(&xPA) + xQB = phi.EvaluatePoint(&xQA) + xRB = phi.EvaluatePoint(&xRA) + Fp2Batch3Inv(&xPB.Z, &xQB.Z, &xRB.Z, &invZP, &invZQ, &invZR) + + mul(&pub3Pt[0], &xPB.X, &invZP) + mul(&pub3Pt[1], &xQB.X, &invZQ) + mul(&pub3Pt[2], &xRB.X, &invZR) +} + +// ----------------------------------------------------------------------------- +// Key agreement functions +// + +// Establishing shared keys in in 2-torsion group +func DeriveSecretA(ss, prv []byte, pub3Pt *[3]Fp2) { + var xP, xQ, xQmP ProjectivePoint + var xR ProjectivePoint + var phi isogeny4 + var jInv Fp2 + + // Recover curve coefficients + cparam := params.InitCurve + RecoverCoordinateA(&cparam, &pub3Pt[0], &pub3Pt[1], &pub3Pt[2]) + + // Find kernel of the morphism + xP = ProjectivePoint{X: pub3Pt[0], Z: params.OneFp2} + xQ = ProjectivePoint{X: pub3Pt[1], Z: params.OneFp2} + xQmP = ProjectivePoint{X: pub3Pt[2], Z: params.OneFp2} + xR = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, params.A.SecretBitLen, prv) + + // Traverse isogeny tree + traverseTreeSharedKeyA(&cparam, &xR) + + // Calculate j-invariant on isogeneus curve + c := phi.GenerateCurve(&xR) + RecoverCurveCoefficients4(&cparam, &c) + Jinvariant(&cparam, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(ss, &jInv, params.Bytelen) +} + +// Establishing shared keys in in 3-torsion group +func DeriveSecretB(ss, prv []byte, pub3Pt *[3]Fp2) { + var xP, xQ, xQmP ProjectivePoint + var xR ProjectivePoint + var phi isogeny3 + var jInv Fp2 + + // Recover curve coefficients + cparam := params.InitCurve + RecoverCoordinateA(&cparam, &pub3Pt[0], &pub3Pt[1], &pub3Pt[2]) + + // Find kernel of the morphism + xP = ProjectivePoint{X: pub3Pt[0], Z: params.OneFp2} + xQ = ProjectivePoint{X: pub3Pt[1], Z: params.OneFp2} + xQmP = ProjectivePoint{X: pub3Pt[2], Z: params.OneFp2} + xR = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, params.B.SecretBitLen, prv) + + // Traverse isogeny tree + traverseTreeSharedKeyB(&cparam, &xR) + + // Calculate j-invariant on isogeneus curve + c := phi.GenerateCurve(&xR) + RecoverCurveCoefficients3(&cparam, &c) + Jinvariant(&cparam, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(ss, &jInv, params.Bytelen) +} diff --git a/dh/sidh/internal/p434/curve.go b/dh/sidh/internal/p434/curve.go new file mode 100644 index 0000000..aa02553 --- /dev/null +++ b/dh/sidh/internal/p434/curve.go @@ -0,0 +1,362 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p434 + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Stores isogeny 3 curve constants +type isogeny3 struct { + K1 Fp2 + K2 Fp2 +} + +// Stores isogeny 4 curve constants +type isogeny4 struct { + isogeny3 + K3 Fp2 +} + +// Computes j-invariant for a curve y2=x3+A/Cx+x with A,C in F_(p^2). Result +// is returned in jBytes buffer, encoded in little-endian format. Caller +// provided jBytes buffer has to be big enough to j-invariant value. In case +// of SIDH, buffer size must be at least size of shared secret. +// Implementation corresponds to Algorithm 9 from SIKE. +func Jinvariant(cparams *ProjectiveCurveParameters, j *Fp2) { + var t0, t1 Fp2 + + sqr(j, &cparams.A) // j = A^2 + sqr(&t1, &cparams.C) // t1 = C^2 + add(&t0, &t1, &t1) // t0 = t1 + t1 + sub(&t0, j, &t0) // t0 = j - t0 + sub(&t0, &t0, &t1) // t0 = t0 - t1 + sub(j, &t0, &t1) // t0 = t0 - t1 + sqr(&t1, &t1) // t1 = t1^2 + mul(j, j, &t1) // j = j * t1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t0, &t0, &t0) // t0 = t0 + t0 + sqr(&t1, &t0) // t1 = t0^2 + mul(&t0, &t0, &t1) // t0 = t0 * t1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t0, &t0, &t0) // t0 = t0 + t0 + inv(j, j) // j = 1/j + mul(j, &t0, j) // j = t0 * j +} + +// Given affine points x(P), x(Q) and x(Q-P) in a extension field F_{p^2}, function +// recorvers projective coordinate A of a curve. This is Algorithm 10 from SIKE. +func RecoverCoordinateA(curve *ProjectiveCurveParameters, xp, xq, xr *Fp2) { + var t0, t1 Fp2 + + add(&t1, xp, xq) // t1 = Xp + Xq + mul(&t0, xp, xq) // t0 = Xp * Xq + mul(&curve.A, xr, &t1) // A = X(q-p) * t1 + add(&curve.A, &curve.A, &t0) // A = A + t0 + mul(&t0, &t0, xr) // t0 = t0 * X(q-p) + sub(&curve.A, &curve.A, ¶ms.OneFp2) // A = A - 1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t1, &t1, xr) // t1 = t1 + X(q-p) + add(&t0, &t0, &t0) // t0 = t0 + t0 + sqr(&curve.A, &curve.A) // A = A^2 + inv(&t0, &t0) // t0 = 1/t0 + mul(&curve.A, &curve.A, &t0) // A = A * t0 + sub(&curve.A, &curve.A, &t1) // A = A - t1 +} + +// Computes equivalence (A:C) ~ (A+2C : A-2C) +func CalcCurveParamsEquiv3(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv { + var coef CurveCoefficientsEquiv + var c2 Fp2 + + add(&c2, &cparams.C, &cparams.C) + // A24p = A+2*C + add(&coef.A, &cparams.A, &c2) + // A24m = A-2*C + sub(&coef.C, &cparams.A, &c2) + return coef +} + +// Computes equivalence (A:C) ~ (A+2C : 4C) +func CalcCurveParamsEquiv4(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv { + var coefEq CurveCoefficientsEquiv + + add(&coefEq.C, &cparams.C, &cparams.C) + // A24p = A+2C + add(&coefEq.A, &cparams.A, &coefEq.C) + // C24 = 4*C + add(&coefEq.C, &coefEq.C, &coefEq.C) + return coefEq +} + +// Helper function for RightToLeftLadder(). Returns A+2C / 4. +func CalcAplus2Over4(cparams *ProjectiveCurveParameters) (ret Fp2) { + var tmp Fp2 + + // 2C + add(&tmp, &cparams.C, &cparams.C) + // A+2C + add(&ret, &cparams.A, &tmp) + // 1/4C + add(&tmp, &tmp, &tmp) + inv(&tmp, &tmp) + // A+2C/4C + mul(&ret, &ret, &tmp) + return +} + +// Recovers (A:C) curve parameters from projectively equivalent (A+2C:A-2C). +func RecoverCurveCoefficients3(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) { + add(&cparams.A, &coefEq.A, &coefEq.C) + // cparams.A = 2*(A+2C+A-2C) = 4A + add(&cparams.A, &cparams.A, &cparams.A) + // cparams.C = (A+2C-A+2C) = 4C + sub(&cparams.C, &coefEq.A, &coefEq.C) + return +} + +// Recovers (A:C) curve parameters from projectively equivalent (A+2C:4C). +func RecoverCurveCoefficients4(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) { + // cparams.C = (4C)*1/2=2C + mul(&cparams.C, &coefEq.C, ¶ms.HalfFp2) + // cparams.A = A+2C - 2C = A + sub(&cparams.A, &coefEq.A, &cparams.C) + // cparams.C = 2C * 1/2 = C + mul(&cparams.C, &cparams.C, ¶ms.HalfFp2) +} + +// Combined coordinate doubling and differential addition. Takes projective points +// P,Q,Q-P and (A+2C)/4C curve E coefficient. Returns 2*P and P+Q calculated on E. +// Function is used only by RightToLeftLadder. Corresponds to Algorithm 5 of SIKE +func xDbladd(P, Q, QmP *ProjectivePoint, a24 *Fp2) (dblP, PaQ ProjectivePoint) { + var t0, t1, t2 Fp2 + + xQmP, zQmP := &QmP.X, &QmP.Z + xPaQ, zPaQ := &PaQ.X, &PaQ.Z + x2P, z2P := &dblP.X, &dblP.Z + xP, zP := &P.X, &P.Z + xQ, zQ := &Q.X, &Q.Z + + add(&t0, xP, zP) // t0 = Xp+Zp + sub(&t1, xP, zP) // t1 = Xp-Zp + sqr(x2P, &t0) // 2P.X = t0^2 + sub(&t2, xQ, zQ) // t2 = Xq-Zq + add(xPaQ, xQ, zQ) // Xp+q = Xq+Zq + mul(&t0, &t0, &t2) // t0 = t0 * t2 + mul(z2P, &t1, &t1) // 2P.Z = t1 * t1 + mul(&t1, &t1, xPaQ) // t1 = t1 * Xp+q + sub(&t2, x2P, z2P) // t2 = 2P.X - 2P.Z + mul(x2P, x2P, z2P) // 2P.X = 2P.X * 2P.Z + mul(xPaQ, a24, &t2) // Xp+q = A24 * t2 + sub(zPaQ, &t0, &t1) // Zp+q = t0 - t1 + add(z2P, xPaQ, z2P) // 2P.Z = Xp+q + 2P.Z + add(xPaQ, &t0, &t1) // Xp+q = t0 + t1 + mul(z2P, z2P, &t2) // 2P.Z = 2P.Z * t2 + sqr(zPaQ, zPaQ) // Zp+q = Zp+q ^ 2 + sqr(xPaQ, xPaQ) // Xp+q = Xp+q ^ 2 + mul(zPaQ, xQmP, zPaQ) // Zp+q = Xq-p * Zp+q + mul(xPaQ, zQmP, xPaQ) // Xp+q = Zq-p * Xp+q + return +} + +// Given the curve parameters, xP = x(P), computes xP = x([2^k]P) +// Safe to overlap xP, x2P. +func Pow2k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) { + var t0, t1 Fp2 + + x, z := &xP.X, &xP.Z + for i := uint32(0); i < k; i++ { + sub(&t0, x, z) // t0 = Xp - Zp + add(&t1, x, z) // t1 = Xp + Zp + sqr(&t0, &t0) // t0 = t0 ^ 2 + sqr(&t1, &t1) // t1 = t1 ^ 2 + mul(z, ¶ms.C, &t0) // Z2p = C24 * t0 + mul(x, z, &t1) // X2p = Z2p * t1 + sub(&t1, &t1, &t0) // t1 = t1 - t0 + mul(&t0, ¶ms.A, &t1) // t0 = A24+ * t1 + add(z, z, &t0) // Z2p = Z2p + t0 + mul(z, z, &t1) // Zp = Z2p * t1 + } +} + +// Given the curve parameters, xP = x(P), and k >= 0, compute xP = x([3^k]P). +// +// Safe to overlap xP, xR. +func Pow3k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) { + var t0, t1, t2, t3, t4, t5, t6 Fp2 + + x, z := &xP.X, &xP.Z + for i := uint32(0); i < k; i++ { + sub(&t0, x, z) // t0 = Xp - Zp + sqr(&t2, &t0) // t2 = t0^2 + add(&t1, x, z) // t1 = Xp + Zp + sqr(&t3, &t1) // t3 = t1^2 + add(&t4, &t1, &t0) // t4 = t1 + t0 + sub(&t0, &t1, &t0) // t0 = t1 - t0 + sqr(&t1, &t4) // t1 = t4^2 + sub(&t1, &t1, &t3) // t1 = t1 - t3 + sub(&t1, &t1, &t2) // t1 = t1 - t2 + mul(&t5, &t3, ¶ms.A) // t5 = t3 * A24+ + mul(&t3, &t3, &t5) // t3 = t5 * t3 + mul(&t6, &t2, ¶ms.C) // t6 = t2 * A24- + mul(&t2, &t2, &t6) // t2 = t2 * t6 + sub(&t3, &t2, &t3) // t3 = t2 - t3 + sub(&t2, &t5, &t6) // t2 = t5 - t6 + mul(&t1, &t2, &t1) // t1 = t2 * t1 + add(&t2, &t3, &t1) // t2 = t3 + t1 + sqr(&t2, &t2) // t2 = t2^2 + mul(x, &t2, &t4) // X3p = t2 * t4 + sub(&t1, &t3, &t1) // t1 = t3 - t1 + sqr(&t1, &t1) // t1 = t1^2 + mul(z, &t1, &t0) // Z3p = t1 * t0 + } +} + +// Set (y1, y2, y3) = (1/x1, 1/x2, 1/x3). +// +// All xi, yi must be distinct. +func Fp2Batch3Inv(x1, x2, x3, y1, y2, y3 *Fp2) { + var x1x2, t Fp2 + + mul(&x1x2, x1, x2) // x1*x2 + mul(&t, &x1x2, x3) // 1/(x1*x2*x3) + inv(&t, &t) + mul(y1, &t, x2) // 1/x1 + mul(y1, y1, x3) + mul(y2, &t, x1) // 1/x2 + mul(y2, y2, x3) + mul(y3, &t, &x1x2) // 1/x3 +} + +// Scalarmul3Pt is a right-to-left point multiplication that given the +// x-coordinate of P, Q and P-Q calculates the x-coordinate of R=Q+[scalar]P. +// nbits must be smaller or equal to len(scalar). +func ScalarMul3Pt(cparams *ProjectiveCurveParameters, P, Q, PmQ *ProjectivePoint, nbits uint, scalar []uint8) ProjectivePoint { + var R0, R2, R1 ProjectivePoint + aPlus2Over4 := CalcAplus2Over4(cparams) + R1 = *P + R2 = *PmQ + R0 = *Q + + // Iterate over the bits of the scalar, bottom to top + prevBit := uint8(0) + for i := uint(0); i < nbits; i++ { + bit := (scalar[i>>3] >> (i & 7) & 1) + swap := prevBit ^ bit + prevBit = bit + cswap(&R1.X, &R1.Z, &R2.X, &R2.Z, swap) + R0, R2 = xDbladd(&R0, &R2, &R1, &aPlus2Over4) + } + cswap(&R1.X, &R1.Z, &R2.X, &R2.Z, prevBit) + return R1 +} + +// Given a three-torsion point p = x(PB) on the curve E_(A:C), construct the +// three-isogeny phi : E_(A:C) -> E_(A:C)/ = E_(A':C'). +// +// Input: (XP_3: ZP_3), where P_3 has exact order 3 on E_A/C +// Output: * Curve coordinates (A' + 2C', A' - 2C') corresponding to E_A'/C' = A_E/C/ +// * Isogeny phi with constants in F_p^2 +func (phi *isogeny3) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv { + var t0, t1, t2, t3, t4 Fp2 + var coefEq CurveCoefficientsEquiv + var K1, K2 = &phi.K1, &phi.K2 + + sub(K1, &p.X, &p.Z) // K1 = XP3 - ZP3 + sqr(&t0, K1) // t0 = K1^2 + add(K2, &p.X, &p.Z) // K2 = XP3 + ZP3 + sqr(&t1, K2) // t1 = K2^2 + add(&t2, &t0, &t1) // t2 = t0 + t1 + add(&t3, K1, K2) // t3 = K1 + K2 + sqr(&t3, &t3) // t3 = t3^2 + sub(&t3, &t3, &t2) // t3 = t3 - t2 + add(&t2, &t1, &t3) // t2 = t1 + t3 + add(&t3, &t3, &t0) // t3 = t3 + t0 + add(&t4, &t3, &t0) // t4 = t3 + t0 + add(&t4, &t4, &t4) // t4 = t4 + t4 + add(&t4, &t1, &t4) // t4 = t1 + t4 + mul(&coefEq.C, &t2, &t4) // A24m = t2 * t4 + add(&t4, &t1, &t2) // t4 = t1 + t2 + add(&t4, &t4, &t4) // t4 = t4 + t4 + add(&t4, &t0, &t4) // t4 = t0 + t4 + mul(&t4, &t3, &t4) // t4 = t3 * t4 + sub(&t0, &t4, &coefEq.C) // t0 = t4 - A24m + add(&coefEq.A, &coefEq.C, &t0) // A24p = A24m + t0 + return coefEq +} + +// Given a 3-isogeny phi and a point pB = x(PB), compute x(QB), the x-coordinate +// of the image QB = phi(PB) of PB under phi : E_(A:C) -> E_(A':C'). +// +// The output xQ = x(Q) is then a point on the curve E_(A':C'); the curve +// parameters are returned by the GenerateCurve function used to construct phi. +func (phi *isogeny3) EvaluatePoint(p *ProjectivePoint) ProjectivePoint { + var t0, t1, t2 Fp2 + var q ProjectivePoint + var K1, K2 = &phi.K1, &phi.K2 + var px, pz = &p.X, &p.Z + + add(&t0, px, pz) // t0 = XQ + ZQ + sub(&t1, px, pz) // t1 = XQ - ZQ + mul(&t0, K1, &t0) // t2 = K1 * t0 + mul(&t1, K2, &t1) // t1 = K2 * t1 + add(&t2, &t0, &t1) // t2 = t0 + t1 + sub(&t0, &t1, &t0) // t0 = t1 - t0 + sqr(&t2, &t2) // t2 = t2 ^ 2 + sqr(&t0, &t0) // t0 = t0 ^ 2 + mul(&q.X, px, &t2) // XQ'= XQ * t2 + mul(&q.Z, pz, &t0) // ZQ'= ZQ * t0 + return q +} + +// Given a four-torsion point p = x(PB) on the curve E_(A:C), construct the +// four-isogeny phi : E_(A:C) -> E_(A:C)/ = E_(A':C'). +// +// Input: (XP_4: ZP_4), where P_4 has exact order 4 on E_A/C +// Output: * Curve coordinates (A' + 2C', 4C') corresponding to E_A'/C' = A_E/C/ +// * Isogeny phi with constants in F_p^2 +func (phi *isogeny4) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv { + var coefEq CurveCoefficientsEquiv + var xp4, zp4 = &p.X, &p.Z + var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3 + + sub(K2, xp4, zp4) + add(K3, xp4, zp4) + sqr(K1, zp4) + add(K1, K1, K1) + sqr(&coefEq.C, K1) + add(K1, K1, K1) + sqr(&coefEq.A, xp4) + add(&coefEq.A, &coefEq.A, &coefEq.A) + sqr(&coefEq.A, &coefEq.A) + return coefEq +} + +// Given a 4-isogeny phi and a point xP = x(P), compute x(Q), the x-coordinate +// of the image Q = phi(P) of P under phi : E_(A:C) -> E_(A':C'). +// +// Input: Isogeny returned by GenerateCurve and point q=(Qx,Qz) from E0_A/C +// Output: Corresponding point q from E1_A'/C', where E1 is 4-isogenous to E0 +func (phi *isogeny4) EvaluatePoint(p *ProjectivePoint) ProjectivePoint { + var t0, t1 Fp2 + var q = *p + var xq, zq = &q.X, &q.Z + var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3 + + add(&t0, xq, zq) + sub(&t1, xq, zq) + mul(xq, &t0, K2) + mul(zq, &t1, K3) + mul(&t0, &t0, &t1) + mul(&t0, &t0, K1) + add(&t1, xq, zq) + sub(zq, xq, zq) + sqr(&t1, &t1) + sqr(zq, zq) + add(xq, &t0, &t1) + sub(&t0, zq, &t0) + mul(xq, xq, &t1) + mul(zq, zq, &t0) + return q +} diff --git a/dh/sidh/internal/p434/curve_test.go b/dh/sidh/internal/p434/curve_test.go new file mode 100644 index 0000000..119684a --- /dev/null +++ b/dh/sidh/internal/p434/curve_test.go @@ -0,0 +1,100 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p434 + +import ( + "bytes" + "testing" + + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +func vartimeEqProjFp2(lhs, rhs *ProjectivePoint) bool { + var t0, t1 Fp2 + mul(&t0, &lhs.X, &rhs.Z) + mul(&t1, &lhs.Z, &rhs.X) + return vartimeEqFp2(&t0, &t1) +} + +func toAffine(point *ProjectivePoint) *Fp2 { + var affineX Fp2 + inv(&affineX, &point.Z) + mul(&affineX, &affineX, &point.X) + return &affineX +} + +func Test_jInvariant(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var jbufRes = make([]byte, params.SharedSecretSize) + var jbufExp = make([]byte, params.SharedSecretSize) + var jInv Fp2 + + Jinvariant(&curve, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(jbufRes, &jInv, params.Bytelen) + + jInv = expectedJ + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(jbufExp, &jInv, params.Bytelen) + + if !bytes.Equal(jbufRes[:], jbufExp[:]) { + t.Error("Computed incorrect j-invariant: found\n", jbufRes, "\nexpected\n", jbufExp) + } +} + +func TestProjectivePointVartimeEq(t *testing.T) { + var xP ProjectivePoint + + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + xQ := xP + + // Scale xQ, which results in the same projective point + mul(&xQ.X, &xQ.X, &curveA) + mul(&xQ.Z, &xQ.Z, &curveA) + if !vartimeEqProjFp2(&xP, &xQ) { + t.Error("Expected the scaled point to be equal to the original") + } +} + +func TestPointMulVersusSage(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var cparams = CalcCurveParamsEquiv4(&curve) + var xP ProjectivePoint + + // x 2 + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow2k(&xP, &cparams, 1) + afxQ := toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP2) { + t.Error("\nExpected\n", affineXP2, "\nfound\n", afxQ) + } + + // x 4 + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow2k(&xP, &cparams, 2) + afxQ = toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP4) { + t.Error("\nExpected\n", affineXP4, "\nfound\n", afxQ) + } +} + +func TestPointMul9VersusSage(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var cparams = CalcCurveParamsEquiv3(&curve) + var xP ProjectivePoint + + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow3k(&xP, &cparams, 2) + afxQ := toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP9) { + t.Error("\nExpected\n", affineXP9, "\nfound\n", afxQ) + } +} + +func BenchmarkThreePointLadder(b *testing.B) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + for n := 0; n < b.N; n++ { + ScalarMul3Pt(&curve, &threePointLadderInputs[0], &threePointLadderInputs[1], &threePointLadderInputs[2], uint(len(scalar3Pt)*8), scalar3Pt[:]) + } +} diff --git a/dh/sidh/internal/p434/fp2.go b/dh/sidh/internal/p434/fp2.go new file mode 100644 index 0000000..05ec5a5 --- /dev/null +++ b/dh/sidh/internal/p434/fp2.go @@ -0,0 +1,195 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p434 + +import ( + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Montgomery multiplication. Input values must be already +// in Montgomery domain. +func mulP(dest, lhs, rhs *common.Fp) { + var ab common.FpX2 + mulP434(&ab, lhs, rhs) // = a*b*R*R + rdcP434(dest, &ab) // = a*b*R mod p +} + +// Set dest = x^((p-3)/4). If x is square, this is 1/sqrt(x). +// Uses variation of sliding-window algorithm from with window size +// of 5 and least to most significant bit sliding (left-to-right) +// See HAC 14.85 for general description. +// +// Allowed to overlap x with dest. +// All values in Montgomery domains +// Set dest = x^(2^k), for k >= 1, by repeated squarings. +func p34(dest, x *common.Fp) { + var lookup [16]common.Fp + + // This performs sum(powStrategy) + 1 squarings and len(lookup) + len(mulStrategy) + // multiplications. + powStrategy := []uint8{3, 10, 7, 5, 6, 5, 3, 8, 4, 7, 5, 6, 4, 5, 9, 6, 3, 11, 5, 5, 2, 8, 4, 7, 7, 8, 5, 6, 4, 8, 5, 2, 10, 6, 5, 4, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1} + mulStrategy := []uint8{2, 15, 9, 8, 14, 12, 2, 8, 5, 15, 8, 15, 6, 6, 3, 2, 0, 10, 9, 13, 1, 12, 3, 7, 1, 10, 8, 11, 2, 15, 14, 1, 11, 12, 14, 3, 11, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0} + initialMul := uint8(8) + + // Precompute lookup table of odd multiples of x for window + // size k=5. + var xx common.Fp + mulP(&xx, x, x) + lookup[0] = *x + for i := 1; i < 16; i++ { + mulP(&lookup[i], &lookup[i-1], &xx) + } + + // Now lookup = {x, x^3, x^5, ... } + // so that lookup[i] = x^{2*i + 1} + // so that lookup[k/2] = x^k, for odd k + *dest = lookup[initialMul] + for i := uint8(0); i < uint8(len(powStrategy)); i++ { + mulP(dest, dest, dest) + for j := uint8(1); j < powStrategy[i]; j++ { + mulP(dest, dest, dest) + } + mulP(dest, dest, &lookup[mulStrategy[i]]) + } +} + +func add(dest, lhs, rhs *common.Fp2) { + addP434(&dest.A, &lhs.A, &rhs.A) + addP434(&dest.B, &lhs.B, &rhs.B) +} + +func sub(dest, lhs, rhs *common.Fp2) { + subP434(&dest.A, &lhs.A, &rhs.A) + subP434(&dest.B, &lhs.B, &rhs.B) +} + +func mul(dest, lhs, rhs *common.Fp2) { + var bMinA, cMinD common.Fp + var ac, bd common.FpX2 + var adPlusBc common.FpX2 + var acMinBd common.FpX2 + + // Let (a,b,c,d) = (lhs.a,lhs.b,rhs.a,rhs.b). + // + // (a + bi)*(c + di) = (a*c - b*d) + (a*d + b*c)i + // + // Use Karatsuba's trick: note that + // + // (b - a)*(c - d) = (b*c + a*d) - a*c - b*d + // + // so (a*d + b*c) = (b-a)*(c-d) + a*c + b*d. + mulP434(&ac, &lhs.A, &rhs.A) // = a*c*R*R + mulP434(&bd, &lhs.B, &rhs.B) // = b*d*R*R + subP434(&bMinA, &lhs.B, &lhs.A) // = (b-a)*R + subP434(&cMinD, &rhs.A, &rhs.B) // = (c-d)*R + mulP434(&adPlusBc, &bMinA, &cMinD) // = (b-a)*(c-d)*R*R + adlP434(&adPlusBc, &adPlusBc, &ac) // = ((b-a)*(c-d) + a*c)*R*R + adlP434(&adPlusBc, &adPlusBc, &bd) // = ((b-a)*(c-d) + a*c + b*d)*R*R + rdcP434(&dest.B, &adPlusBc) // = (a*d + b*c)*R mod p + sulP434(&acMinBd, &ac, &bd) // = (a*c - b*d)*R*R + rdcP434(&dest.A, &acMinBd) // = (a*c - b*d)*R mod p +} + +// Set dest = 1/x +// +// Allowed to overlap dest with x. +// +// Returns dest to allow chaining operations. +func inv(dest, x *common.Fp2) { + var e1, e2 common.FpX2 + var f1, f2 common.Fp + + // We want to compute + // + // 1 1 (a - bi) (a - bi) + // -------- = -------- -------- = ----------- + // (a + bi) (a + bi) (a - bi) (a^2 + b^2) + // + // Letting c = 1/(a^2 + b^2), this is + // + // 1/(a+bi) = a*c - b*ci. + + mulP434(&e1, &x.A, &x.A) // = a*a*R*R + mulP434(&e2, &x.B, &x.B) // = b*b*R*R + adlP434(&e1, &e1, &e2) // = (a^2 + b^2)*R*R + rdcP434(&f1, &e1) // = (a^2 + b^2)*R mod p + // Now f1 = a^2 + b^2 + + mulP(&f2, &f1, &f1) + p34(&f2, &f2) + mulP(&f2, &f2, &f2) + mulP(&f2, &f2, &f1) + + mulP434(&e1, &x.A, &f2) + rdcP434(&dest.A, &e1) + + subP434(&f1, &common.Fp{}, &x.B) + mulP434(&e1, &f1, &f2) + rdcP434(&dest.B, &e1) +} + +func sqr(dest, x *common.Fp2) { + var a2, aPlusB, aMinusB common.Fp + var a2MinB2, ab2 common.FpX2 + + a := &x.A + b := &x.B + + // (a + bi)*(a + bi) = (a^2 - b^2) + 2abi. + addP434(&a2, a, a) // = a*R + a*R = 2*a*R + addP434(&aPlusB, a, b) // = a*R + b*R = (a+b)*R + subP434(&aMinusB, a, b) // = a*R - b*R = (a-b)*R + mulP434(&a2MinB2, &aPlusB, &aMinusB) // = (a+b)*(a-b)*R*R = (a^2 - b^2)*R*R + mulP434(&ab2, &a2, b) // = 2*a*b*R*R + rdcP434(&dest.A, &a2MinB2) // = (a^2 - b^2)*R mod p + rdcP434(&dest.B, &ab2) // = 2*a*b*R mod p +} + +// In case choice == 1, performs following swap in constant time: +// xPx <-> xQx +// xPz <-> xQz +// Otherwise returns xPx, xPz, xQx, xQz unchanged +func cswap(xPx, xPz, xQx, xQz *common.Fp2, choice uint8) { + cswapP434(&xPx.A, &xQx.A, choice) + cswapP434(&xPx.B, &xQx.B, choice) + cswapP434(&xPz.A, &xQz.A, choice) + cswapP434(&xPz.B, &xQz.B, choice) +} + +// Converts in.A and in.B to Montgomery domain and stores +// in 'out' +// out.A = in.A * R mod p +// out.B = in.B * R mod p +// Performs v = v*R^2*R^(-1) mod p, for both in.A and in.B +func ToMontgomery(out, in *common.Fp2) { + var aRR common.FpX2 + + // a*R*R + mulP434(&aRR, &in.A, &P434R2) + // a*R mod p + rdcP434(&out.A, &aRR) + mulP434(&aRR, &in.B, &P434R2) + rdcP434(&out.B, &aRR) +} + +// Converts in.A and in.B from Montgomery domain and stores +// in 'out' +// out.A = in.A mod p +// out.B = in.B mod p +// +// After returning from the call 'in' is not modified. +func FromMontgomery(out, in *common.Fp2) { + var aR common.FpX2 + + // convert from montgomery domain + copy(aR[:], in.A[:]) + rdcP434(&out.A, &aR) // = a mod p in [0, 2p) + modP434(&out.A) // = a mod p in [0, p) + for i := range aR { + aR[i] = 0 + } + copy(aR[:], in.B[:]) + rdcP434(&out.B, &aR) + modP434(&out.B) +} diff --git a/dh/sidh/internal/p434/fp2_test.go b/dh/sidh/internal/p434/fp2_test.go new file mode 100644 index 0000000..4499361 --- /dev/null +++ b/dh/sidh/internal/p434/fp2_test.go @@ -0,0 +1,245 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p434 + +import ( + "math/rand" + "reflect" + "testing" + "testing/quick" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +type testParams struct { + Point common.ProjectivePoint + Cparam common.ProjectiveCurveParameters + ExtElem common.Fp2 +} + +// Returns true if lhs = rhs. Takes variable time. +func vartimeEqFp2(lhs, rhs *common.Fp2) bool { + a := *lhs + b := *rhs + + modP434(&a.A) + modP434(&a.B) + modP434(&b.A) + modP434(&b.B) + + eq := true + for i := 0; i < FpWords && eq; i++ { + eq = eq && (a.A[i] == b.A[i]) + eq = eq && (a.B[i] == b.B[i]) + } + return eq +} + +func (testParams) generateFp2(rand *rand.Rand) common.Fp2 { + // Generation strategy: low limbs taken from [0,2^64); high limb + // taken from smaller range + // + // Size hint is ignored since all elements are fixed size. + // + // Field elements taken in range [0,2p). Emulate this by capping + // the high limb by the top digit of 2*p-1: + // + // sage: (2*p-1).digits(2^64)[-1] + // + // This still allows generating values >= 2p, but hopefully that + // excess is OK (and if it's not, we'll find out, because it's for + // testing...) + highLimb := rand.Uint64() % P434x2[FpWords-1] + fpElementGen := func() (fp common.Fp) { + for i := 0; i < (FpWords - 1); i++ { + fp[i] = rand.Uint64() + } + fp[FpWords-1] = highLimb + return fp + } + return common.Fp2{A: fpElementGen(), B: fpElementGen()} +} + +func (c testParams) Generate(rand *rand.Rand, size int) reflect.Value { + return reflect.ValueOf( + testParams{ + common.ProjectivePoint{ + X: c.generateFp2(rand), + Z: c.generateFp2(rand), + }, + common.ProjectiveCurveParameters{ + A: c.generateFp2(rand), + C: c.generateFp2(rand), + }, + c.generateFp2(rand), + }) +} + +func TestOne(t *testing.T) { + var tmp common.Fp2 + + mul(&tmp, ¶ms.OneFp2, ¶ms.A.AffineP) + if !vartimeEqFp2(&tmp, ¶ms.A.AffineP) { + t.Error("Not equal 1") + } +} + +func TestFp2ToBytesRoundTrip(t *testing.T) { + roundTrips := func(x testParams) bool { + var xBytes = make([]byte, 2*params.Bytelen) + var xPrime common.Fp2 + + common.Fp2ToBytes(xBytes[:], &x.ExtElem, params.Bytelen) + common.BytesToFp2(&xPrime, xBytes[:], params.Bytelen) + return vartimeEqFp2(&xPrime, &x.ExtElem) + } + + if err := quick.Check(roundTrips, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2MulDistributesOverAdd(t *testing.T) { + mulDistributesOverAdd := func(x, y, z testParams) bool { + // Compute t1 = (x+y)*z + t1 := new(common.Fp2) + add(t1, &x.ExtElem, &y.ExtElem) + mul(t1, t1, &z.ExtElem) + + // Compute t2 = x*z + y*z + t2 := new(common.Fp2) + t3 := new(common.Fp2) + mul(t2, &x.ExtElem, &z.ExtElem) + mul(t3, &y.ExtElem, &z.ExtElem) + add(t2, t2, t3) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(mulDistributesOverAdd, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2MulIsAssociative(t *testing.T) { + isAssociative := func(x, y, z testParams) bool { + // Compute t1 = (x*y)*z + t1 := new(common.Fp2) + mul(t1, &x.ExtElem, &y.ExtElem) + mul(t1, t1, &z.ExtElem) + + // Compute t2 = (y*z)*x + t2 := new(common.Fp2) + mul(t2, &y.ExtElem, &z.ExtElem) + mul(t2, t2, &x.ExtElem) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(isAssociative, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2SquareMatchesMul(t *testing.T) { + sqrMatchesMul := func(x testParams) bool { + // Compute t1 = (x*x) + t1 := new(common.Fp2) + mul(t1, &x.ExtElem, &x.ExtElem) + + // Compute t2 = x^2 + t2 := new(common.Fp2) + sqr(t2, &x.ExtElem) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(sqrMatchesMul, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2Inv(t *testing.T) { + inverseIsCorrect := func(x testParams) bool { + z := new(common.Fp2) + inv(z, &x.ExtElem) + + // Now z = (1/x), so (z * x) * x == x + mul(z, z, &x.ExtElem) + mul(z, z, &x.ExtElem) + + return vartimeEqFp2(z, &x.ExtElem) + } + + // This is more expensive; run fewer tests + var quickCheckConfig = &quick.Config{MaxCount: (1 << 11)} + if err := quick.Check(inverseIsCorrect, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2Batch3Inv(t *testing.T) { + batchInverseIsCorrect := func(x1, x2, x3 testParams) bool { + var x1Inv, x2Inv, x3Inv common.Fp2 + inv(&x1Inv, &x1.ExtElem) + inv(&x2Inv, &x2.ExtElem) + inv(&x3Inv, &x3.ExtElem) + + var y1, y2, y3 common.Fp2 + Fp2Batch3Inv(&x1.ExtElem, &x2.ExtElem, &x3.ExtElem, &y1, &y2, &y3) + + return (vartimeEqFp2(&x1Inv, &y1) && vartimeEqFp2(&x2Inv, &y2) && vartimeEqFp2(&x3Inv, &y3)) + } + + // This is more expensive; run fewer tests + var quickCheckConfig = &quick.Config{MaxCount: (1 << 8)} + if err := quick.Check(batchInverseIsCorrect, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func BenchmarkFp2Mul(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + mul(w, z, z) + } +} + +func BenchmarkFp2Inv(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + inv(w, z) + } +} + +func BenchmarkFp2Square(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + sqr(w, z) + } +} + +func BenchmarkFp2Add(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + add(w, z, z) + } +} + +func BenchmarkFp2Sub(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + sub(w, z, z) + } +} diff --git a/dh/sidh/internal/p434/params.go b/dh/sidh/internal/p434/params.go new file mode 100644 index 0000000..00acaca --- /dev/null +++ b/dh/sidh/internal/p434/params.go @@ -0,0 +1,197 @@ +package p434 + +//go:generate go run ../templates/gen.go P434 + +import ( + "github.com/henrydcase/nobs/dh/sidh/internal/common" + "golang.org/x/sys/cpu" +) + +const ( + // Number of uint64 limbs used to store field element + FpWords = 7 +) + +var ( + // HasADXandBMI2 signals support for ADX and BMI2 + HasADXandBMI2 = cpu.X86.HasBMI2 && cpu.X86.HasADX + + // P434 is a prime used by field Fp434 + P434 = common.Fp{ + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFDC1767AE2FFFFFF, + 0x7BC65C783158AEA3, 0x6CFC5FD681C52056, 0x2341F27177344, + } + + // P434x2 = 2*p434 - 1 + P434x2 = common.Fp{ + 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFB82ECF5C5FFFFFF, + 0xF78CB8F062B15D47, 0xD9F8BFAD038A40AC, 0x4683E4E2EE688, + } + + // P434p1 = p434 + 1 + P434p1 = common.Fp{ + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFDC1767AE3000000, + 0x7BC65C783158AEA3, 0x6CFC5FD681C52056, 0x0002341F27177344, + } + + // P434R2 = (2^448)^2 mod p + P434R2 = common.Fp{ + 0x28E55B65DCD69B30, 0xACEC7367768798C2, 0xAB27973F8311688D, 0x175CC6AF8D6C7C0B, + 0xABCD92BF2DDE347E, 0x69E16A61C7686D9A, 0x000025A89BCDD12A, + } + + // 1/2 * R mod p + half = common.Fp2{ + A: common.Fp{ + 0x0000000000003A16, 0x0000000000000000, 0x0000000000000000, 0x5C87FA027E000000, + 0x6C00D27DAACFD66A, 0x74992A2A2FBBA086, 0x0000767753DE976D}, + } + + // 1*R mod p + one = common.Fp2{ + A: common.Fp{ + 0x000000000000742C, 0x0000000000000000, 0x0000000000000000, 0xB90FF404FC000000, + 0xD801A4FB559FACD4, 0xE93254545F77410C, 0x0000ECEEA7BD2EDA}, + } + + // 6*R mod p + six = common.Fp2{ + A: common.Fp{ + 0x000000000002B90A, 0x0000000000000000, 0x0000000000000000, 0x5ADCCB2822000000, + 0x187D24F39F0CAFB4, 0x9D353A4D394145A0, 0x00012559A0403298}, + } + + P434p1Zeros = 3 + + params = common.SidhParams{ + ID: common.Fp434, + // SIDH public key byte size. + PublicKeySize: 330, + // SIDH shared secret byte size. + SharedSecretSize: 110, + InitCurve: common.ProjectiveCurveParameters{ + A: six, + C: one, + }, + A: common.DomainParams{ + // The x-coordinate of PA + AffineP: common.Fp2{ + A: common.Fp{ + 0x05ADF455C5C345BF, 0x91935C5CC767AC2B, 0xAFE4E879951F0257, 0x70E792DC89FA27B1, + 0xF797F526BB48C8CD, 0x2181DB6131AF621F, 0x00000A1C08B1ECC4, + }, + B: common.Fp{ + 0x74840EB87CDA7788, 0x2971AA0ECF9F9D0B, 0xCB5732BDF41715D5, 0x8CD8E51F7AACFFAA, + 0xA7F424730D7E419F, 0xD671EB919A179E8C, 0x0000FFA26C5A924A, + }, + }, + // The x-coordinate of QA + AffineQ: common.Fp2{ + A: common.Fp{ + 0xFEC6E64588B7273B, 0xD2A626D74CBBF1C6, 0xF8F58F07A78098C7, 0xE23941F470841B03, + 0x1B63EDA2045538DD, 0x735CFEB0FFD49215, 0x0001C4CB77542876, + }, + B: common.Fp{ + 0xADB0F733C17FFDD6, 0x6AFFBD037DA0A050, 0x680EC43DB144E02F, 0x1E2E5D5FF524E374, + 0xE2DDA115260E2995, 0xA6E4B552E2EDE508, 0x00018ECCDDF4B53E, + }, + }, + + // The x-coordinate of RA = PA-QA + AffineR: common.Fp2{ + A: common.Fp{ + 0x01BA4DB518CD6C7D, 0x2CB0251FE3CC0611, 0x259B0C6949A9121B, 0x60E17AC16D2F82AD, + 0x3AA41F1CE175D92D, 0x413FBE6A9B9BC4F3, 0x00022A81D8D55643, + }, + B: common.Fp{ + 0xB8ADBC70FC82E54A, 0xEF9CDDB0D5FADDED, 0x5820C734C80096A0, 0x7799994BAA96E0E4, + 0x044961599E379AF8, 0xDB2B94FBF09F27E2, 0x0000B87FC716C0C6, + }, + }, + // Max size of secret key for 2-torsion group, corresponds to 2^e2 - 1 + SecretBitLen: 216, + // SecretBitLen in bytes. + SecretByteLen: 28, + // 2-torsion group computation strategy + IsogenyStrategy: []uint32{ + 0x30, 0x1C, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, + 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, + 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x0D, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02, + 0x01, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x05, 0x04, + 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x15, 0x0C, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x05, 0x03, 0x02, 0x01, + 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x09, 0x05, 0x03, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, + 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01}, + }, + B: common.DomainParams{ + // The x-coordinate of PB + AffineP: common.Fp2{ + A: common.Fp{ + 0x6E5497556EDD48A3, 0x2A61B501546F1C05, 0xEB919446D049887D, 0x5864A4A69D450C4F, + 0xB883F276A6490D2B, 0x22CC287022D5F5B9, 0x0001BED4772E551F, + }, + B: common.Fp{ + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + }, + }, + // The x-coordinate of QB + AffineQ: common.Fp2{ + A: common.Fp{ + 0xFAE2A3F93D8B6B8E, 0x494871F51700FE1C, 0xEF1A94228413C27C, 0x498FF4A4AF60BD62, + 0xB00AD2A708267E8A, 0xF4328294E017837F, 0x000034080181D8AE, + }, + B: common.Fp{ + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + }, + }, + // The x-coordinate of RB = PB - QB + AffineR: common.Fp2{ + A: common.Fp{ + 0x283B34FAFEFDC8E4, 0x9208F44977C3E647, 0x7DEAE962816F4E9A, 0x68A2BA8AA262EC9D, + 0x8176F112EA43F45B, 0x02106D022634F504, 0x00007E8A50F02E37, + }, + B: common.Fp{ + 0xB378B7C1DA22CCB1, 0x6D089C99AD1D9230, 0xEBE15711813E2369, 0x2B35A68239D48A53, + 0x445F6FD138407C93, 0xBEF93B29A3F6B54B, 0x000173FA910377D3, + }, + }, + // Size of secret key for 3-torsion group, corresponds to log_2(3^e3) - 1. + SecretBitLen: 217, + // SecretBitLen in bytes. + SecretByteLen: 28, + // 3-torsion group computation strategy + IsogenyStrategy: []uint32{ + 0x42, 0x21, 0x11, 0x09, 0x05, 0x03, 0x02, 0x01, 0x01, 0x01, + 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, + 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x10, + 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, + 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, + 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, + 0x01, 0x20, 0x10, 0x08, 0x04, 0x03, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x10, 0x08, 0x04, 0x02, 0x01, + 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, + 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, + 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}, + }, + OneFp2: one, + HalfFp2: half, + MsgLen: 16, + // SIKEp434 provides 192 bit of classical security ([SIKE], 5.1) + KemSize: 16, + // ceil(434+7/8) + Bytelen: 55, + CiphertextSize: 16 + 330, + } +) + +func init() { + common.Register(common.Fp434, ¶ms) +} diff --git a/dh/sidh/internal/p434/params_test.go b/dh/sidh/internal/p434/params_test.go new file mode 100644 index 0000000..6ec524f --- /dev/null +++ b/dh/sidh/internal/p434/params_test.go @@ -0,0 +1,69 @@ +package p434 + +// Contains values used by tests +import ( + "testing/quick" + + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Values omputed using Sage +var ( + expectedJ = Fp2{ + A: Fp{0x38ECC0A0F53BACB4, 0xF987759E90A6C0DD, 0xC3007B353AE699F6, 0xB2B7E62A4F182414, 0xA65A854B34034F1B, 0xC71EAD20BE427422, 0xFC94F0D8DD51}, + B: Fp{0xFC3B47615764A089, 0x9D32DF1BA8CF22E5, 0x7B895EF92F44C690, 0xE83667F85BBFA475, 0xD44627DCF539CA71, 0x9619A0E7D6657401, 0x4BC5BF1D9B01}} + + curveA = Fp2{ + A: Fp{0x13A5A42C36E5E170, 0xC801DC4104E2C1DC, 0xB102AE39A7E24F31, 0x2FB616EA2E824C97, 0xB97073B55448AA67, 0x607266F7204D90DA, 0x1E98FE9739F27}, + B: Fp{0x000000000000742C, 0x0000000000000000, 0x0000000000000000, 0xB90FF404FC000000, 0xD801A4FB559FACD4, 0xE93254545F77410C, 0x0ECEEA7BD2EDA}} + + curveC = Fp2{ + A: Fp{0x8CBBA3505E5EDAB2, 0xB1DE7B91FBB77718, 0x6957392BFDC9BEB0, 0xC258E527E05FDDDE, 0x8C5FC7ADF5E50AE9, 0x1B2149FBEC2F4D18, 0x19FC2A5C79942}, + B: Fp{0x000000000000E858, 0x0000000000000000, 0x0000000000000000, 0x721FE809F8000000, 0xB00349F6AB3F59A9, 0xD264A8A8BEEE8219, 0x1D9DD4F7A5DB5}} + + affineXP = Fp2{ + A: Fp{0x775C29CA29E5FC3F, 0xCAB15BD1A1AB2754, 0x2C7F5B5DC58096EB, 0x2EE7B0B5A789355A, 0xBBD7BC749FF4D74E, 0x1373A265C9A9D58B, 0x5C183CE99B13}, + B: Fp{0x38CDA704EB4D517C, 0x2F8BA33C91C147D4, 0x4D17E97F04A8D431, 0x5DB8F238AE1B099F, 0x44DC758CE879824C, 0x7E95F1151F6DFA3C, 0xB59F64352B87}} + + affineXP2 = Fp2{ + A: Fp{0x2A5C658FD540804D, 0xA27CDB81FA7C6A5C, 0x6C36B6EB38B1B562, 0xC08642D636AF9A51, 0x36B2323A1279F346, 0x530BF3E8726D8B71, 0x61E38F638919}, + B: Fp{0x5D835C52A68FC93D, 0x9E8FAF973A68306C, 0xB3C28FE9D155F61C, 0xCCE6FA22BC1A1FBF, 0xEAB44D8952802BA5, 0xEAAC0F259AAC3A8F, 0x959B242CE01A}} + + affineXP4 = Fp2{ + A: Fp{0xF824931762C6DC4A, 0xA9B0FD30136F4B50, 0xAF041BBAB14DC6B1, 0x0AD52F55527A9BA2, 0x282B236D61F08C59, 0x5D3D7EC0C5EB9DCB, 0x10BBDDEA44BF7}, + B: Fp{0x77D92493AF97245B, 0xD717FEC838D464C6, 0xCAACD67DB3BF965D, 0x82D59FB89CDC0711, 0xF13CAE433F39CDE1, 0x9B55DFB11A585FFA, 0x0DC8BA1C054D3}} + + affineXP9 = Fp2{ + A: Fp{0x1F6F0785353A02C0, 0xCCB1B8524A63E37F, 0xB283C636B1FDD74C, 0xB76DBFF592DE6FF5, 0x15750EE706F18226, 0x50791362F26E459C, 0x1EA2A9074423}, + B: Fp{0x945C6909DA5039A3, 0x349CFD24FD84FDAF, 0x2FD2F391F2E26E75, 0xEF73E8A634EBDC76, 0x59DDA2622AC22A6C, 0xE0370B80E15F61F4, 0xB302956A0276}} + + // Inputs for testing 3-point-ladder + threePointLadderInputs = []ProjectivePoint{ + // x(P) + { + X: Fp2{ + A: Fp{0x43941FA9244C059E, 0xD1F337D076941189, 0x6B6A8B3A8763C96A, 0x6DF569708D6C9482, 0x487EE5707A52F4AA, 0xDE396F6E2559689E, 0xE5EE3895A8991469, 0x2B0946695790A8}, + B: Fp{0xAB552C0FDAED092E, 0x7DF895E43E7DCB1C, 0x35C700E761920C4B, 0xCC5807DD70DC117A, 0x0884039A5A8DB18A, 0xD04620B3D0738052, 0xA200835605138F10, 0x3FF2E59B2FDC6A}}, + Z: params.OneFp2, + }, + // x(Q) + { + X: Fp2{ + A: Fp{0x77015826982BA1FD, 0x44024489673471E4, 0x1CAA2A5F4D5DA63B, 0xA183C07E50738C01, 0x8B97782D4E1A0DE6, 0x9B819522FBC38280, 0x0BDA46A937FB7B8A, 0x3B3614305914DF}, + B: Fp{0xBF0366E97B3168D9, 0xAA522AC3879CEF0F, 0x0AF5EC975BD035C8, 0x1F26FEE7BBAC165C, 0xA0EE6A637724A6AB, 0xFB52101E36BA3A38, 0xD29CF5E376E17376, 0x1374A50DF57071}}, + Z: params.OneFp2, + }, + // x(P-Q) + { + X: Fp2{ + A: Fp{0xD99279BBD41EA559, 0x35CF18E72F578214, 0x90473B1DC77F73E8, 0xBFFEA930B25D7F66, 0xFD558EA177B900B2, 0x7CFAD273A782A23E, 0x6B1F610822E0F611, 0x26D2D2EF9619B5}, + B: Fp{0x534F83651CBCC75D, 0x591FB4757AED5D08, 0x0B04353D40BED542, 0x829A94703AAC9139, 0x0F9C2E6D7663EB5B, 0x5D2D0F90C283F746, 0x34C872AA12A7676E, 0x0ECDB605FBFA16}}, + Z: params.OneFp2, + }, + } + scalar3Pt = [...]uint8{0x9f, 0x3b, 0xe7, 0xf9, 0xf4, 0x7c, 0xe6, 0xce, 0x79, 0x3e, 0x3d, 0x9f, 0x9f, 0x3b, 0xe7, 0xf9, 0xf4, 0x7c, 0xe6, 0xce, 0x79, 0x3e, 0x3d, 0x9f} +) + +var quickCheckConfig = &quick.Config{ + MaxCount: (1 << 15), +} diff --git a/dh/sidh/p503/arith_amd64.s b/dh/sidh/internal/p503/arith_amd64.s similarity index 94% rename from dh/sidh/p503/arith_amd64.s rename to dh/sidh/internal/p503/arith_amd64.s index 6b664ec..41022c8 100644 --- a/dh/sidh/p503/arith_amd64.s +++ b/dh/sidh/internal/p503/arith_amd64.s @@ -361,7 +361,7 @@ // * MULS: either MULS_128x320_MULX or MULS_128x320_MULX_ADCX_ADOX // Output: OUT 512-bit #define REDC(OUT, IN, MULS) \ - MULS(0(IN), ·p503p1, R8, R9, R10, R11, R12, R13, R14, BX, CX, R15) \ + MULS(0(IN), ·P503p1, R8, R9, R10, R11, R12, R13, R14, BX, CX, R15) \ XORQ R15, R15 \ ADDQ (24)(IN), R8 \ ADCQ (32)(IN), R9 \ @@ -395,7 +395,7 @@ MOVQ R11, (112)(IN) \ MOVQ R12, (120)(IN) \ \ - MULS(16(IN), ·p503p1, R8, R9, R10, R11, R12, R13, R14, BX, CX, R15) \ + MULS(16(IN), ·P503p1, R8, R9, R10, R11, R12, R13, R14, BX, CX, R15) \ XORQ R15, R15 \ ADDQ (40)(IN), R8 \ ADCQ (48)(IN), R9 \ @@ -423,7 +423,7 @@ MOVQ R9, (112)(IN) \ MOVQ R10, (120)(IN) \ \ - MULS(32(IN), ·p503p1, R8, R9, R10, R11, R12, R13, R14, BX, CX, R15) \ + MULS(32(IN), ·P503p1, R8, R9, R10, R11, R12, R13, R14, BX, CX, R15) \ XORQ R15, R15 \ XORQ BX, BX \ ADDQ ( 56)(IN), R8 \ @@ -445,7 +445,7 @@ MOVQ BX, (120)(IN) \ MOVQ R9, ( 0)(OUT) \ // Result: OUT[0] \ - MULS(48(IN), ·p503p1, R8, R9, R10, R11, R12, R13, R14, BX, CX, R15) \ + MULS(48(IN), ·P503p1, R8, R9, R10, R11, R12, R13, R14, BX, CX, R15) \ ADDQ ( 72)(IN), R8 \ ADCQ ( 80)(IN), R9 \ ADCQ ( 88)(IN), R10 \ @@ -461,7 +461,7 @@ MOVQ R13, (48)(OUT) \ // Result: OUT[6] and OUT[7] MOVQ R14, (56)(OUT) -TEXT ·fp503StrongReduce(SB), NOSPLIT, $0-8 +TEXT ·modP503(SB), NOSPLIT, $0-8 MOVQ x+0(FP), REG_P1 // Zero AX for later use: @@ -508,52 +508,43 @@ TEXT ·fp503StrongReduce(SB), NOSPLIT, $0-8 RET -TEXT ·fp503ConditionalSwap(SB),NOSPLIT,$0-17 +TEXT ·cswapP503(SB),NOSPLIT,$0-17 MOVQ x+0(FP), REG_P1 MOVQ y+8(FP), REG_P2 - MOVBLZX choice+16(FP), AX // AL = 0 or 1 - - // Make AX, so that either all bits are set or non - // AX = 0 or 1 - NEGQ AX - - // Fill xmm15. After this step first half of XMM15 is - // just zeros and second half is whatever in AX - MOVQ AX, X15 - - // Copy lower double word everywhere else. So that - // XMM15=AL|AL|AL|AL. As AX has either all bits set - // or non result will be that XMM15 has also either - // all bits set or non of them. - PSHUFD $0, X15, X15 + MOVB choice+16(FP), AL // AL = 0 or 1 + MOVBLZX AL, AX // AX = 0 or 1 + NEGQ AX // AX = 0x00..00 or 0xff..ff #ifndef CSWAP_BLOCK -#define CSWAP_BLOCK(idx) \ - MOVOU (idx*16)(REG_P1), X0 \ - MOVOU (idx*16)(REG_P2), X1 \ - \ // X2 = mask & (X0 ^ X1) - MOVO X1, X2 \ - PXOR X0, X2 \ - PAND X15, X2 \ - \ - PXOR X2, X0 \ - PXOR X2, X1 \ - \ - MOVOU X0, (idx*16)(REG_P1) \ - MOVOU X1, (idx*16)(REG_P2) +#define CSWAP_BLOCK(idx) \ + MOVQ (idx*8)(REG_P1), BX \ // BX = x[idx] + MOVQ (idx*8)(REG_P2), CX \ // CX = y[idx] + MOVQ CX, DX \ // DX = y[idx] + XORQ BX, DX \ // DX = y[idx] ^ x[idx] + ANDQ AX, DX \ // DX = (y[idx] ^ x[idx]) & mask + XORQ DX, BX \ // BX = (y[idx] ^ x[idx]) & mask) ^ x[idx] = x[idx] or y[idx] + XORQ DX, CX \ // CX = (y[idx] ^ x[idx]) & mask) ^ y[idx] = y[idx] or x[idx] + MOVQ BX, (idx*8)(REG_P1) \ + MOVQ CX, (idx*8)(REG_P2) #endif - CSWAP_BLOCK(0) - CSWAP_BLOCK(1) - CSWAP_BLOCK(2) - CSWAP_BLOCK(3) + + CSWAP_BLOCK(0) + CSWAP_BLOCK(1) + CSWAP_BLOCK(2) + CSWAP_BLOCK(3) + CSWAP_BLOCK(4) + CSWAP_BLOCK(5) + CSWAP_BLOCK(6) + CSWAP_BLOCK(7) #ifdef CSWAP_BLOCK #undef CSWAP_BLOCK #endif + RET -TEXT ·fp503AddReduced(SB),NOSPLIT,$0-24 +TEXT ·addP503(SB),NOSPLIT,$0-24 MOVQ z+0(FP), REG_P3 MOVQ x+8(FP), REG_P1 @@ -634,7 +625,7 @@ TEXT ·fp503AddReduced(SB),NOSPLIT,$0-24 MOVQ (56)(REG_P3), AX; ADCQ R14, AX; MOVQ AX, (56)(REG_P3) RET -TEXT ·fp503SubReduced(SB), NOSPLIT, $0-24 +TEXT ·subP503(SB), NOSPLIT, $0-24 MOVQ z+0(FP), REG_P3 MOVQ x+8(FP), REG_P1 @@ -700,9 +691,9 @@ TEXT ·fp503SubReduced(SB), NOSPLIT, $0-24 RET -TEXT ·fp503Mul(SB), NOSPLIT, $104-24 - MOVQ z+ 0(FP), CX - MOVQ x+ 8(FP), REG_P1 +TEXT ·mulP503(SB), NOSPLIT, $104-24 + MOVQ z+0(FP), CX + MOVQ x+8(FP), REG_P1 MOVQ y+16(FP), REG_P2 // Check wether to use optimized implementation @@ -1198,7 +1189,7 @@ mul_with_mulx: MUL(CX, REG_P1, REG_P2, MULS256_MULX) RET -TEXT ·fp503MontgomeryReduce(SB), $0-16 +TEXT ·rdcP503(SB), $0-16 MOVQ z+0(FP), REG_P2 MOVQ x+8(FP), REG_P1 @@ -1525,42 +1516,7 @@ redc_with_mulx: REDC(REG_P2, REG_P1, MULS_128x320_MULX) RET -TEXT ·fp503AddLazy(SB), NOSPLIT, $0-24 - - MOVQ z+0(FP), REG_P3 - MOVQ x+8(FP), REG_P1 - MOVQ y+16(FP), REG_P2 - - MOVQ (REG_P1), R8 - MOVQ (8)(REG_P1), R9 - MOVQ (16)(REG_P1), R10 - MOVQ (24)(REG_P1), R11 - MOVQ (32)(REG_P1), R12 - MOVQ (40)(REG_P1), R13 - MOVQ (48)(REG_P1), R14 - MOVQ (56)(REG_P1), R15 - - ADDQ (REG_P2), R8 - ADCQ (8)(REG_P2), R9 - ADCQ (16)(REG_P2), R10 - ADCQ (24)(REG_P2), R11 - ADCQ (32)(REG_P2), R12 - ADCQ (40)(REG_P2), R13 - ADCQ (48)(REG_P2), R14 - ADCQ (56)(REG_P2), R15 - - MOVQ R8, (REG_P3) - MOVQ R9, (8)(REG_P3) - MOVQ R10, (16)(REG_P3) - MOVQ R11, (24)(REG_P3) - MOVQ R12, (32)(REG_P3) - MOVQ R13, (40)(REG_P3) - MOVQ R14, (48)(REG_P3) - MOVQ R15, (56)(REG_P3) - - RET - -TEXT ·fp503X2AddLazy(SB), NOSPLIT, $0-24 +TEXT ·adlP503(SB), NOSPLIT, $0-24 MOVQ z+0(FP), REG_P3 MOVQ x+8(FP), REG_P1 @@ -1622,7 +1578,7 @@ TEXT ·fp503X2AddLazy(SB), NOSPLIT, $0-24 RET -TEXT ·fp503X2SubLazy(SB), NOSPLIT, $0-24 +TEXT ·sulP503(SB), NOSPLIT, $0-24 MOVQ z+0(FP), REG_P3 MOVQ x+8(FP), REG_P1 diff --git a/dh/sidh/p503/arith_amd64_test.go b/dh/sidh/internal/p503/arith_amd64_test.go similarity index 87% rename from dh/sidh/p503/arith_amd64_test.go rename to dh/sidh/internal/p503/arith_amd64_test.go index 8406a0b..f853607 100644 --- a/dh/sidh/p503/arith_amd64_test.go +++ b/dh/sidh/internal/p503/arith_amd64_test.go @@ -1,13 +1,17 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + // +build amd64,!noasm package p503 import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - cpu "github.com/henrydcase/nobs/utils" "reflect" "testing" "testing/quick" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" + "golang.org/x/sys/cpu" ) type OptimFlag uint @@ -29,19 +33,19 @@ func resetCpuFeatures() { // Utility function used for testing Mul implementations. Tests caller provided // mulFunc against mul() func testMul(t *testing.T, f1, f2 OptimFlag) { - doMulTest := func(multiplier, multiplicant FpElement) bool { + doMulTest := func(multiplier, multiplicant common.Fp) bool { defer resetCpuFeatures() - var resMulRef, resMulOptim FpElementX2 + var resMulRef, resMulOptim common.FpX2 // Compute multiplier*multiplicant with first implementation HasBMI2 = (kUse_MULX & f1) == kUse_MULX HasADXandBMI2 = (kUse_MULXandADxX & f1) == kUse_MULXandADxX - fp503Mul(&resMulOptim, &multiplier, &multiplicant) + mulP503(&resMulOptim, &multiplier, &multiplicant) // Compute multiplier*multiplicant with second implementation HasBMI2 = (kUse_MULX & f2) == kUse_MULX HasADXandBMI2 = (kUse_MULXandADxX & f2) == kUse_MULXandADxX - fp503Mul(&resMulRef, &multiplier, &multiplicant) + mulP503(&resMulRef, &multiplier, &multiplicant) // Compare results return reflect.DeepEqual(resMulRef, resMulOptim) @@ -55,20 +59,20 @@ func testMul(t *testing.T, f1, f2 OptimFlag) { // Utility function used for testing REDC implementations. Tests caller provided // redcFunc against redc() func testRedc(t *testing.T, f1, f2 OptimFlag) { - doRedcTest := func(aRR FpElementX2) bool { + doRedcTest := func(aRR common.FpX2) bool { defer resetCpuFeatures() - var resRedcF1, resRedcF2 FpElement + var resRedcF1, resRedcF2 common.Fp var aRRcpy = aRR // Compute redc with first implementation HasBMI2 = (kUse_MULX & f1) == kUse_MULX HasADXandBMI2 = (kUse_MULXandADxX & f1) == kUse_MULXandADxX - fp503MontgomeryReduce(&resRedcF1, &aRR) + rdcP503(&resRedcF1, &aRR) // Compute redc with second implementation HasBMI2 = (kUse_MULX & f2) == kUse_MULX HasADXandBMI2 = (kUse_MULXandADxX & f2) == kUse_MULXandADxX - fp503MontgomeryReduce(&resRedcF2, &aRRcpy) + rdcP503(&resRedcF2, &aRRcpy) // Compare results return reflect.DeepEqual(resRedcF2, resRedcF1) diff --git a/dh/sidh/p503/arith_arm64.s b/dh/sidh/internal/p503/arith_arm64.s similarity index 90% rename from dh/sidh/p503/arith_arm64.s rename to dh/sidh/internal/p503/arith_arm64.s index 0889bfd..559806a 100644 --- a/dh/sidh/p503/arith_arm64.s +++ b/dh/sidh/internal/p503/arith_arm64.s @@ -2,7 +2,7 @@ #include "textflag.h" -TEXT ·fp503ConditionalSwap(SB), NOSPLIT, $0-17 +TEXT ·cswapP503(SB), NOSPLIT, $0-17 MOVD x+0(FP), R0 MOVD y+8(FP), R1 MOVB choice+16(FP), R2 @@ -49,7 +49,7 @@ TEXT ·fp503ConditionalSwap(SB), NOSPLIT, $0-17 RET -TEXT ·fp503AddReduced(SB), NOSPLIT, $0-24 +TEXT ·addP503(SB), NOSPLIT, $0-24 MOVD z+0(FP), R2 MOVD x+8(FP), R0 MOVD y+16(FP), R1 @@ -75,14 +75,14 @@ TEXT ·fp503AddReduced(SB), NOSPLIT, $0-24 ADC R14, R10 // Subtract 2 * p503 in R11-R17 from the result in R3-R10 - LDP ·p503x2+0(SB), (R11, R12) - LDP ·p503x2+24(SB), (R13, R14) + LDP ·P503x2+0(SB), (R11, R12) + LDP ·P503x2+24(SB), (R13, R14) SUBS R11, R3 SBCS R12, R4 - LDP ·p503x2+40(SB), (R15, R16) + LDP ·P503x2+40(SB), (R15, R16) SBCS R12, R5 SBCS R13, R6 - MOVD ·p503x2+56(SB), R17 + MOVD ·P503x2+56(SB), R17 SBCS R14, R7 SBCS R15, R8 SBCS R16, R9 @@ -113,7 +113,7 @@ TEXT ·fp503AddReduced(SB), NOSPLIT, $0-24 RET -TEXT ·fp503SubReduced(SB), NOSPLIT, $0-24 +TEXT ·subP503(SB), NOSPLIT, $0-24 MOVD z+0(FP), R2 MOVD x+8(FP), R0 MOVD y+16(FP), R1 @@ -140,14 +140,14 @@ TEXT ·fp503SubReduced(SB), NOSPLIT, $0-24 SBC ZR, ZR, R19 // If x - y < 0, R19 is 1 and 2 * p503 should be added - LDP ·p503x2+0(SB), (R11, R12) - LDP ·p503x2+24(SB), (R13, R14) + LDP ·P503x2+0(SB), (R11, R12) + LDP ·P503x2+24(SB), (R13, R14) AND R19, R11 AND R19, R12 - LDP ·p503x2+40(SB), (R15, R16) + LDP ·P503x2+40(SB), (R15, R16) AND R19, R13 AND R19, R14 - MOVD ·p503x2+56(SB), R17 + MOVD ·P503x2+56(SB), R17 AND R19, R15 AND R19, R16 AND R19, R17 @@ -167,38 +167,7 @@ TEXT ·fp503SubReduced(SB), NOSPLIT, $0-24 RET -TEXT ·fp503AddLazy(SB), NOSPLIT, $0-24 - MOVD z+0(FP), R2 - MOVD x+8(FP), R0 - MOVD y+16(FP), R1 - - // Load first summand into R3-R10 - // Add first summand and second summand and store result in R3-R10 - LDP 0(R0), (R3, R4) - LDP 0(R1), (R11, R12) - LDP 16(R0), (R5, R6) - LDP 16(R1), (R13, R14) - ADDS R11, R3 - ADCS R12, R4 - STP (R3, R4), 0(R2) - ADCS R13, R5 - ADCS R14, R6 - STP (R5, R6), 16(R2) - - LDP 32(R0), (R7, R8) - LDP 32(R1), (R11, R12) - LDP 48(R0), (R9, R10) - LDP 48(R1), (R13, R14) - ADCS R11, R7 - ADCS R12, R8 - STP (R7, R8), 32(R2) - ADCS R13, R9 - ADC R14, R10 - STP (R9, R10), 48(R2) - - RET - -TEXT ·fp503X2AddLazy(SB), NOSPLIT, $0-24 +TEXT ·adlP503(SB), NOSPLIT, $0-24 MOVD z+0(FP), R2 MOVD x+8(FP), R0 MOVD y+16(FP), R1 @@ -249,7 +218,7 @@ TEXT ·fp503X2AddLazy(SB), NOSPLIT, $0-24 RET -TEXT ·fp503X2SubLazy(SB), NOSPLIT, $0-24 +TEXT ·sulP503(SB), NOSPLIT, $0-24 MOVD z+0(FP), R2 MOVD x+8(FP), R0 MOVD y+16(FP), R1 @@ -296,11 +265,11 @@ TEXT ·fp503X2SubLazy(SB), NOSPLIT, $0-24 SBC ZR, ZR, R15 // If x - y < 0, R15 is 1 and p503 should be added - LDP ·p503+16(SB), (R16, R17) - LDP ·p503+32(SB), (R19, R20) + LDP ·P503+16(SB), (R16, R17) + LDP ·P503+32(SB), (R19, R20) AND R15, R16 AND R15, R17 - LDP ·p503+48(SB), (R21, R22) + LDP ·P503+48(SB), (R21, R22) AND R15, R19 AND R15, R20 AND R15, R21 @@ -413,7 +382,7 @@ TEXT ·fp503X2SubLazy(SB), NOSPLIT, $0-24 // This implements two-level Karatsuba with a 128x128 Comba multiplier // at the bottom -TEXT ·fp503Mul(SB), NOSPLIT, $0-24 +TEXT ·mulP503(SB), NOSPLIT, $0-24 MOVD z+0(FP), R2 MOVD x+8(FP), R0 MOVD y+16(FP), R1 @@ -601,15 +570,15 @@ TEXT ·fp503Mul(SB), NOSPLIT, $0-24 // This implements the shifted 2^(B*w) Montgomery reduction from // https://eprint.iacr.org/2016/986.pdf with B = 4, w = 64 -TEXT ·fp503MontgomeryReduce(SB), NOSPLIT, $0-16 +TEXT ·rdcP503(SB), NOSPLIT, $0-16 MOVD x+8(FP), R0 // Load x0-x1 LDP 0(R0), (R2, R3) // Load the prime constant in R25-R29 - LDP ·p503p1s8+32(SB), (R25, R26) - LDP ·p503p1s8+48(SB), (R27, R29) + LDP ·P503p1s8+32(SB), (R25, R26) + LDP ·P503p1s8+48(SB), (R27, R29) // [x0,x1] * p503p1s8 to R4-R9 MUL R2, R25, R4 // x0 * p503p1s8[0] @@ -752,23 +721,23 @@ TEXT ·fp503MontgomeryReduce(SB), NOSPLIT, $0-16 RET -TEXT ·fp503StrongReduce(SB), NOSPLIT, $0-8 +TEXT ·modP503(SB), NOSPLIT, $0-8 MOVD x+0(FP), R0 // Keep x in R1-R8, p503 in R9-R14, subtract to R1-R8 - LDP ·p503+16(SB), (R9, R10) + LDP ·P503+16(SB), (R9, R10) LDP 0(R0), (R1, R2) LDP 16(R0), (R3, R4) SUBS R9, R1 SBCS R9, R2 LDP 32(R0), (R5, R6) - LDP ·p503+32(SB), (R11, R12) + LDP ·P503+32(SB), (R11, R12) SBCS R9, R3 SBCS R10, R4 LDP 48(R0), (R7, R8) - LDP ·p503+48(SB), (R13, R14) + LDP ·P503+48(SB), (R13, R14) SBCS R11, R5 SBCS R12, R6 diff --git a/dh/sidh/p503/arith_decl.go b/dh/sidh/internal/p503/arith_decl.go similarity index 57% rename from dh/sidh/p503/arith_decl.go rename to dh/sidh/internal/p503/arith_decl.go index cb2745c..6241726 100644 --- a/dh/sidh/p503/arith_decl.go +++ b/dh/sidh/internal/p503/arith_decl.go @@ -1,46 +1,45 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + // +build amd64,!noasm arm64,!noasm package p503 import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" + . "github.com/henrydcase/nobs/dh/sidh/internal/common" ) // If choice = 0, leave x,y unchanged. If choice = 1, set x,y = y,x. // If choice is neither 0 nor 1 then behaviour is undefined. // This function executes in constant time. //go:noescape -func fp503ConditionalSwap(x, y *FpElement, choice uint8) +func cswapP503(x, y *Fp, choice uint8) // Compute z = x + y (mod p). //go:noescape -func fp503AddReduced(z, x, y *FpElement) +func addP503(z, x, y *Fp) // Compute z = x - y (mod p). //go:noescape -func fp503SubReduced(z, x, y *FpElement) +func subP503(z, x, y *Fp) // Compute z = x + y, without reducing mod p. //go:noescape -func fp503AddLazy(z, x, y *FpElement) - -// Compute z = x + y, without reducing mod p. -//go:noescape -func fp503X2AddLazy(z, x, y *FpElementX2) +func adlP503(z, x, y *FpX2) // Compute z = x - y, without reducing mod p. //go:noescape -func fp503X2SubLazy(z, x, y *FpElementX2) +func sulP503(z, x, y *FpX2) // Reduce a field element in [0, 2*p) to one in [0,p). //go:noescape -func fp503StrongReduce(x *FpElement) +func modP503(x *Fp) // Computes z = x * y. //go:noescape -func fp503Mul(z *FpElementX2, x, y *FpElement) +func mulP503(z *FpX2, x, y *Fp) // Computes the Montgomery reduction z = x R^{-1} (mod 2*p). On return value // of x may be changed. z=x not allowed. //go:noescape -func fp503MontgomeryReduce(z *FpElement, x *FpElementX2) +func rdcP503(z *Fp, x *FpX2) diff --git a/dh/sidh/internal/p503/arith_generic.go b/dh/sidh/internal/p503/arith_generic.go new file mode 100644 index 0000000..ac83432 --- /dev/null +++ b/dh/sidh/internal/p503/arith_generic.go @@ -0,0 +1,192 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +// +build noasm !amd64,!arm64 + +package p503 + +import ( + "math/bits" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Compute z = x + y (mod p). +func addP503(z, x, y *common.Fp) { + var carry uint64 + + // z=x+y % P503 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Add64(x[i], y[i], carry) + } + + // z = z - P503x2 + carry = 0 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Sub64(z[i], P503x2[i], carry) + } + + // if z<0 add P503x2 back + mask := uint64(0 - carry) + carry = 0 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Add64(z[i], P503x2[i]&mask, carry) + } +} + +// Compute z = x - y (mod p). +func subP503(z, x, y *common.Fp) { + var borrow uint64 + + for i := 0; i < FpWords; i++ { + z[i], borrow = bits.Sub64(x[i], y[i], borrow) + } + + mask := uint64(0 - borrow) + borrow = 0 + + for i := 0; i < FpWords; i++ { + z[i], borrow = bits.Add64(z[i], P503x2[i]&mask, borrow) + } +} + +// Conditionally swaps bits in x and y in constant time. +// mask indicates bits to be swapped (set bits are swapped) +// For details see "Hackers Delight, 2.20" +// +// Implementation doesn't actually depend on a prime field. +func cswapP503(x, y *common.Fp, mask uint8) { + var tmp, mask64 uint64 + + mask64 = 0 - uint64(mask) + for i := 0; i < FpWords; i++ { + tmp = mask64 & (x[i] ^ y[i]) + x[i] = tmp ^ x[i] + y[i] = tmp ^ y[i] + } +} + +// Perform Montgomery reduction: set z = x R^{-1} (mod 2*p) +// with R=2^(FpWords*64). Destroys the input value. +func rdcP503(z *common.Fp, x *common.FpX2) { + var carry, t, u, v uint64 + var hi, lo uint64 + var count int + + count = P503p1Zeros + + for i := 0; i < FpWords; i++ { + for j := 0; j < i; j++ { + if j < (i - count + 1) { + hi, lo = bits.Mul64(z[j], P503p1[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + } + v, carry = bits.Add64(v, x[i], 0) + u, carry = bits.Add64(u, 0, carry) + t += carry + + z[i] = v + v = u + u = t + t = 0 + } + + for i := FpWords; i < 2*FpWords-1; i++ { + if count > 0 { + count-- + } + for j := i - FpWords + 1; j < FpWords; j++ { + if j < (FpWords - count) { + hi, lo = bits.Mul64(z[j], P503p1[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + } + v, carry = bits.Add64(v, x[i], 0) + u, carry = bits.Add64(u, 0, carry) + + t += carry + z[i-FpWords] = v + v = u + u = t + t = 0 + } + v, _ = bits.Add64(v, x[2*FpWords-1], 0) + z[FpWords-1] = v +} + +// Compute z = x * y. +func mulP503(z *common.FpX2, x, y *common.Fp) { + var u, v, t uint64 + var hi, lo uint64 + var carry uint64 + + for i := uint64(0); i < FpWords; i++ { + for j := uint64(0); j <= i; j++ { + hi, lo = bits.Mul64(x[j], y[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + z[i] = v + v = u + u = t + t = 0 + } + + for i := FpWords; i < (2*FpWords)-1; i++ { + for j := i - FpWords + 1; j < FpWords; j++ { + hi, lo = bits.Mul64(x[j], y[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + z[i] = v + v = u + u = t + t = 0 + } + z[2*FpWords-1] = v +} + +// Compute z = x + y, without reducing mod p. +func adlP503(z, x, y *common.FpX2) { + var carry uint64 + for i := 0; i < 2*FpWords; i++ { + z[i], carry = bits.Add64(x[i], y[i], carry) + } +} + +// Reduce a field element in [0, 2*p) to one in [0,p). +func modP503(x *common.Fp) { + var borrow, mask uint64 + for i := 0; i < FpWords; i++ { + x[i], borrow = bits.Sub64(x[i], P503[i], borrow) + } + + // Sets all bits if borrow = 1 + mask = 0 - borrow + borrow = 0 + for i := 0; i < FpWords; i++ { + x[i], borrow = bits.Add64(x[i], P503[i]&mask, borrow) + } +} + +// Compute z = x - y, without reducing mod p. +func sulP503(z, x, y *common.FpX2) { + var borrow, mask uint64 + for i := 0; i < 2*FpWords; i++ { + z[i], borrow = bits.Sub64(x[i], y[i], borrow) + } + + // Sets all bits if borrow = 1 + mask = 0 - borrow + borrow = 0 + for i := FpWords; i < 2*FpWords; i++ { + z[i], borrow = bits.Add64(z[i], P503[i-FpWords]&mask, borrow) + } +} diff --git a/dh/sidh/internal/p503/arith_test.go b/dh/sidh/internal/p503/arith_test.go new file mode 100644 index 0000000..47a37a8 --- /dev/null +++ b/dh/sidh/internal/p503/arith_test.go @@ -0,0 +1,101 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p503 + +import ( + "testing" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Package-level storage for this field element is intended to deter +// compiler optimizations. +var ( + benchmarkFp common.Fp + benchmarkFpX2 common.FpX2 + bench_x = common.Fp{17026702066521327207, 5108203422050077993, 10225396685796065916, 11153620995215874678, 6531160855165088358, 15302925148404145445, 1248821577836769963, 9789766903037985294, 7493111552032041328, 10838999828319306046, 18103257655515297935, 27403304611634} + bench_y = common.Fp{4227467157325093378, 10699492810770426363, 13500940151395637365, 12966403950118934952, 16517692605450415877, 13647111148905630666, 14223628886152717087, 7167843152346903316, 15855377759596736571, 4300673881383687338, 6635288001920617779, 30486099554235} + bench_z = common.FpX2{1595347748594595712, 10854920567160033970, 16877102267020034574, 12435724995376660096, 3757940912203224231, 8251999420280413600, 3648859773438820227, 17622716832674727914, 11029567000887241528, 11216190007549447055, 17606662790980286987, 4720707159513626555, 12887743598335030915, 14954645239176589309, 14178817688915225254, 1191346797768989683, 12629157932334713723, 6348851952904485603, 16444232588597434895, 7809979927681678066, 14642637672942531613, 3092657597757640067, 10160361564485285723, 240071237} +) + +func TestFpCswap(t *testing.T) { + var one = common.Fp{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + var two = common.Fp{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} + + var x = one + var y = two + + cswapP503(&x, &y, 0) + for i := 0; i < FpWords; i++ { + if (x[i] != one[i]) || (y[i] != two[i]) { + t.Error("Found", x, "expected", two) + } + } + + cswapP503(&x, &y, 1) + for i := 0; i < FpWords; i++ { + if (x[i] != two[i]) || (y[i] != one[i]) { + t.Error("Found", x, "expected", two) + } + } +} + +// Benchmarking for field arithmetic +func BenchmarkMul(b *testing.B) { + for n := 0; n < b.N; n++ { + mulP503(&benchmarkFpX2, &bench_x, &bench_y) + } +} + +func BenchmarkRdc(b *testing.B) { + z := bench_z + + // This benchmark actually computes garbage, because + // rdcP503 mangles its input, but since it's + // constant-time that shouldn't matter for the benchmarks. + for n := 0; n < b.N; n++ { + rdcP503(&benchmarkFp, &z) + } +} + +func BenchmarkAdd(b *testing.B) { + for n := 0; n < b.N; n++ { + addP503(&benchmarkFp, &bench_x, &bench_y) + } +} + +func BenchmarkSub(b *testing.B) { + for n := 0; n < b.N; n++ { + subP503(&benchmarkFp, &bench_x, &bench_y) + } +} + +func BenchmarkCswap(b *testing.B) { + x, y := bench_x, bench_y + for n := 0; n < b.N; n++ { + cswapP503(&x, &y, 1) + cswapP503(&x, &y, 0) + } +} + +func BenchmarkMod(b *testing.B) { + x := bench_x + for n := 0; n < b.N; n++ { + modP503(&x) + } +} + +func BenchmarkX2AddLazy(b *testing.B) { + x, y, z := bench_z, bench_z, bench_z + for n := 0; n < b.N; n++ { + adlP503(&x, &y, &z) + } +} + +func BenchmarkX2SubLazy(b *testing.B) { + x, y, z := bench_z, bench_z, bench_z + for n := 0; n < b.N; n++ { + sulP503(&x, &y, &z) + } +} diff --git a/dh/sidh/internal/p503/core.go b/dh/sidh/internal/p503/core.go new file mode 100644 index 0000000..cf128d0 --- /dev/null +++ b/dh/sidh/internal/p503/core.go @@ -0,0 +1,282 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p503 + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// ----------------------------------------------------------------------------- +// Functions for traversing isogeny trees acoording to strategy. Key type 'A' is +// + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreePublicKeyA(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny4 + + cparam := CalcCurveParamsEquiv4(curve) + strat := params.A.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow2k(xR, &cparam, 2*k) + i += int(k) + } + cparam = phi.GenerateCurve(xR) + + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + *phiP = phi.EvaluatePoint(phiP) + *phiQ = phi.EvaluatePoint(phiQ) + *phiR = phi.EvaluatePoint(phiR) + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR needed +// for public key generation. +func traverseTreeSharedKeyA(curve *ProjectiveCurveParameters, xR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny4 + + cparam := CalcCurveParamsEquiv4(curve) + strat := params.A.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow2k(xR, &cparam, 2*k) + i += int(k) + } + cparam = phi.GenerateCurve(xR) + + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreePublicKeyB(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny3 + + cparam := CalcCurveParamsEquiv3(curve) + strat := params.B.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow3k(xR, &cparam, k) + i += int(k) + } + + cparam = phi.GenerateCurve(xR) + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + *phiP = phi.EvaluatePoint(phiP) + *phiQ = phi.EvaluatePoint(phiQ) + *phiR = phi.EvaluatePoint(phiR) + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreeSharedKeyB(curve *ProjectiveCurveParameters, xR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny3 + + cparam := CalcCurveParamsEquiv3(curve) + strat := params.B.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow3k(xR, &cparam, k) + i += int(k) + } + + cparam = phi.GenerateCurve(xR) + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Generate a public key in the 2-torsion group. Public key is a set +// of three x-coordinates: xP,xQ,x(P-Q), where P,Q are points on E_a(Fp2) +func PublicKeyGenA(pub3Pt *[3]Fp2, prvBytes []byte) { + var xPA, xQA, xRA ProjectivePoint + var xPB, xQB, xRB, xR ProjectivePoint + var invZP, invZQ, invZR Fp2 + var phi isogeny4 + + // Load points for A + xPA = ProjectivePoint{X: params.A.AffineP, Z: params.OneFp2} + xQA = ProjectivePoint{X: params.A.AffineQ, Z: params.OneFp2} + xRA = ProjectivePoint{X: params.A.AffineR, Z: params.OneFp2} + + // Load points for B + xRB = ProjectivePoint{X: params.B.AffineR, Z: params.OneFp2} + xQB = ProjectivePoint{X: params.B.AffineQ, Z: params.OneFp2} + xPB = ProjectivePoint{X: params.B.AffineP, Z: params.OneFp2} + + // Find isogeny kernel + xR = ScalarMul3Pt(¶ms.InitCurve, &xPA, &xQA, &xRA, params.A.SecretBitLen, prvBytes) + traverseTreePublicKeyA(¶ms.InitCurve, &xR, &xPB, &xQB, &xRB) + + // Secret isogeny + phi.GenerateCurve(&xR) + xPA = phi.EvaluatePoint(&xPB) + xQA = phi.EvaluatePoint(&xQB) + xRA = phi.EvaluatePoint(&xRB) + Fp2Batch3Inv(&xPA.Z, &xQA.Z, &xRA.Z, &invZP, &invZQ, &invZR) + + mul(&pub3Pt[0], &xPA.X, &invZP) + mul(&pub3Pt[1], &xQA.X, &invZQ) + mul(&pub3Pt[2], &xRA.X, &invZR) +} + +// Generate a public key in the 2-torsion group. Public key is a set +// of three x-coordinates: xP,xQ,x(P-Q), where P,Q are points on E_a(Fp2) +func PublicKeyGenB(pub3Pt *[3]Fp2, prvBytes []byte) { + var xPB, xQB, xRB, xR ProjectivePoint + var xPA, xQA, xRA ProjectivePoint + var invZP, invZQ, invZR Fp2 + var phi isogeny3 + + // Load points for B + xRB = ProjectivePoint{X: params.B.AffineR, Z: params.OneFp2} + xQB = ProjectivePoint{X: params.B.AffineQ, Z: params.OneFp2} + xPB = ProjectivePoint{X: params.B.AffineP, Z: params.OneFp2} + + // Load points for A + xPA = ProjectivePoint{X: params.A.AffineP, Z: params.OneFp2} + xQA = ProjectivePoint{X: params.A.AffineQ, Z: params.OneFp2} + xRA = ProjectivePoint{X: params.A.AffineR, Z: params.OneFp2} + + // Find isogeny kernel + xR = ScalarMul3Pt(¶ms.InitCurve, &xPB, &xQB, &xRB, params.B.SecretBitLen, prvBytes) + traverseTreePublicKeyB(¶ms.InitCurve, &xR, &xPA, &xQA, &xRA) + + phi.GenerateCurve(&xR) + xPB = phi.EvaluatePoint(&xPA) + xQB = phi.EvaluatePoint(&xQA) + xRB = phi.EvaluatePoint(&xRA) + Fp2Batch3Inv(&xPB.Z, &xQB.Z, &xRB.Z, &invZP, &invZQ, &invZR) + + mul(&pub3Pt[0], &xPB.X, &invZP) + mul(&pub3Pt[1], &xQB.X, &invZQ) + mul(&pub3Pt[2], &xRB.X, &invZR) +} + +// ----------------------------------------------------------------------------- +// Key agreement functions +// + +// Establishing shared keys in in 2-torsion group +func DeriveSecretA(ss, prv []byte, pub3Pt *[3]Fp2) { + var xP, xQ, xQmP ProjectivePoint + var xR ProjectivePoint + var phi isogeny4 + var jInv Fp2 + + // Recover curve coefficients + cparam := params.InitCurve + RecoverCoordinateA(&cparam, &pub3Pt[0], &pub3Pt[1], &pub3Pt[2]) + + // Find kernel of the morphism + xP = ProjectivePoint{X: pub3Pt[0], Z: params.OneFp2} + xQ = ProjectivePoint{X: pub3Pt[1], Z: params.OneFp2} + xQmP = ProjectivePoint{X: pub3Pt[2], Z: params.OneFp2} + xR = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, params.A.SecretBitLen, prv) + + // Traverse isogeny tree + traverseTreeSharedKeyA(&cparam, &xR) + + // Calculate j-invariant on isogeneus curve + c := phi.GenerateCurve(&xR) + RecoverCurveCoefficients4(&cparam, &c) + Jinvariant(&cparam, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(ss, &jInv, params.Bytelen) +} + +// Establishing shared keys in in 3-torsion group +func DeriveSecretB(ss, prv []byte, pub3Pt *[3]Fp2) { + var xP, xQ, xQmP ProjectivePoint + var xR ProjectivePoint + var phi isogeny3 + var jInv Fp2 + + // Recover curve coefficients + cparam := params.InitCurve + RecoverCoordinateA(&cparam, &pub3Pt[0], &pub3Pt[1], &pub3Pt[2]) + + // Find kernel of the morphism + xP = ProjectivePoint{X: pub3Pt[0], Z: params.OneFp2} + xQ = ProjectivePoint{X: pub3Pt[1], Z: params.OneFp2} + xQmP = ProjectivePoint{X: pub3Pt[2], Z: params.OneFp2} + xR = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, params.B.SecretBitLen, prv) + + // Traverse isogeny tree + traverseTreeSharedKeyB(&cparam, &xR) + + // Calculate j-invariant on isogeneus curve + c := phi.GenerateCurve(&xR) + RecoverCurveCoefficients3(&cparam, &c) + Jinvariant(&cparam, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(ss, &jInv, params.Bytelen) +} diff --git a/dh/sidh/internal/p503/curve.go b/dh/sidh/internal/p503/curve.go new file mode 100644 index 0000000..395d0cb --- /dev/null +++ b/dh/sidh/internal/p503/curve.go @@ -0,0 +1,362 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p503 + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Stores isogeny 3 curve constants +type isogeny3 struct { + K1 Fp2 + K2 Fp2 +} + +// Stores isogeny 4 curve constants +type isogeny4 struct { + isogeny3 + K3 Fp2 +} + +// Computes j-invariant for a curve y2=x3+A/Cx+x with A,C in F_(p^2). Result +// is returned in jBytes buffer, encoded in little-endian format. Caller +// provided jBytes buffer has to be big enough to j-invariant value. In case +// of SIDH, buffer size must be at least size of shared secret. +// Implementation corresponds to Algorithm 9 from SIKE. +func Jinvariant(cparams *ProjectiveCurveParameters, j *Fp2) { + var t0, t1 Fp2 + + sqr(j, &cparams.A) // j = A^2 + sqr(&t1, &cparams.C) // t1 = C^2 + add(&t0, &t1, &t1) // t0 = t1 + t1 + sub(&t0, j, &t0) // t0 = j - t0 + sub(&t0, &t0, &t1) // t0 = t0 - t1 + sub(j, &t0, &t1) // t0 = t0 - t1 + sqr(&t1, &t1) // t1 = t1^2 + mul(j, j, &t1) // j = j * t1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t0, &t0, &t0) // t0 = t0 + t0 + sqr(&t1, &t0) // t1 = t0^2 + mul(&t0, &t0, &t1) // t0 = t0 * t1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t0, &t0, &t0) // t0 = t0 + t0 + inv(j, j) // j = 1/j + mul(j, &t0, j) // j = t0 * j +} + +// Given affine points x(P), x(Q) and x(Q-P) in a extension field F_{p^2}, function +// recorvers projective coordinate A of a curve. This is Algorithm 10 from SIKE. +func RecoverCoordinateA(curve *ProjectiveCurveParameters, xp, xq, xr *Fp2) { + var t0, t1 Fp2 + + add(&t1, xp, xq) // t1 = Xp + Xq + mul(&t0, xp, xq) // t0 = Xp * Xq + mul(&curve.A, xr, &t1) // A = X(q-p) * t1 + add(&curve.A, &curve.A, &t0) // A = A + t0 + mul(&t0, &t0, xr) // t0 = t0 * X(q-p) + sub(&curve.A, &curve.A, ¶ms.OneFp2) // A = A - 1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t1, &t1, xr) // t1 = t1 + X(q-p) + add(&t0, &t0, &t0) // t0 = t0 + t0 + sqr(&curve.A, &curve.A) // A = A^2 + inv(&t0, &t0) // t0 = 1/t0 + mul(&curve.A, &curve.A, &t0) // A = A * t0 + sub(&curve.A, &curve.A, &t1) // A = A - t1 +} + +// Computes equivalence (A:C) ~ (A+2C : A-2C) +func CalcCurveParamsEquiv3(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv { + var coef CurveCoefficientsEquiv + var c2 Fp2 + + add(&c2, &cparams.C, &cparams.C) + // A24p = A+2*C + add(&coef.A, &cparams.A, &c2) + // A24m = A-2*C + sub(&coef.C, &cparams.A, &c2) + return coef +} + +// Computes equivalence (A:C) ~ (A+2C : 4C) +func CalcCurveParamsEquiv4(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv { + var coefEq CurveCoefficientsEquiv + + add(&coefEq.C, &cparams.C, &cparams.C) + // A24p = A+2C + add(&coefEq.A, &cparams.A, &coefEq.C) + // C24 = 4*C + add(&coefEq.C, &coefEq.C, &coefEq.C) + return coefEq +} + +// Helper function for RightToLeftLadder(). Returns A+2C / 4. +func CalcAplus2Over4(cparams *ProjectiveCurveParameters) (ret Fp2) { + var tmp Fp2 + + // 2C + add(&tmp, &cparams.C, &cparams.C) + // A+2C + add(&ret, &cparams.A, &tmp) + // 1/4C + add(&tmp, &tmp, &tmp) + inv(&tmp, &tmp) + // A+2C/4C + mul(&ret, &ret, &tmp) + return +} + +// Recovers (A:C) curve parameters from projectively equivalent (A+2C:A-2C). +func RecoverCurveCoefficients3(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) { + add(&cparams.A, &coefEq.A, &coefEq.C) + // cparams.A = 2*(A+2C+A-2C) = 4A + add(&cparams.A, &cparams.A, &cparams.A) + // cparams.C = (A+2C-A+2C) = 4C + sub(&cparams.C, &coefEq.A, &coefEq.C) + return +} + +// Recovers (A:C) curve parameters from projectively equivalent (A+2C:4C). +func RecoverCurveCoefficients4(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) { + // cparams.C = (4C)*1/2=2C + mul(&cparams.C, &coefEq.C, ¶ms.HalfFp2) + // cparams.A = A+2C - 2C = A + sub(&cparams.A, &coefEq.A, &cparams.C) + // cparams.C = 2C * 1/2 = C + mul(&cparams.C, &cparams.C, ¶ms.HalfFp2) +} + +// Combined coordinate doubling and differential addition. Takes projective points +// P,Q,Q-P and (A+2C)/4C curve E coefficient. Returns 2*P and P+Q calculated on E. +// Function is used only by RightToLeftLadder. Corresponds to Algorithm 5 of SIKE +func xDbladd(P, Q, QmP *ProjectivePoint, a24 *Fp2) (dblP, PaQ ProjectivePoint) { + var t0, t1, t2 Fp2 + + xQmP, zQmP := &QmP.X, &QmP.Z + xPaQ, zPaQ := &PaQ.X, &PaQ.Z + x2P, z2P := &dblP.X, &dblP.Z + xP, zP := &P.X, &P.Z + xQ, zQ := &Q.X, &Q.Z + + add(&t0, xP, zP) // t0 = Xp+Zp + sub(&t1, xP, zP) // t1 = Xp-Zp + sqr(x2P, &t0) // 2P.X = t0^2 + sub(&t2, xQ, zQ) // t2 = Xq-Zq + add(xPaQ, xQ, zQ) // Xp+q = Xq+Zq + mul(&t0, &t0, &t2) // t0 = t0 * t2 + mul(z2P, &t1, &t1) // 2P.Z = t1 * t1 + mul(&t1, &t1, xPaQ) // t1 = t1 * Xp+q + sub(&t2, x2P, z2P) // t2 = 2P.X - 2P.Z + mul(x2P, x2P, z2P) // 2P.X = 2P.X * 2P.Z + mul(xPaQ, a24, &t2) // Xp+q = A24 * t2 + sub(zPaQ, &t0, &t1) // Zp+q = t0 - t1 + add(z2P, xPaQ, z2P) // 2P.Z = Xp+q + 2P.Z + add(xPaQ, &t0, &t1) // Xp+q = t0 + t1 + mul(z2P, z2P, &t2) // 2P.Z = 2P.Z * t2 + sqr(zPaQ, zPaQ) // Zp+q = Zp+q ^ 2 + sqr(xPaQ, xPaQ) // Xp+q = Xp+q ^ 2 + mul(zPaQ, xQmP, zPaQ) // Zp+q = Xq-p * Zp+q + mul(xPaQ, zQmP, xPaQ) // Xp+q = Zq-p * Xp+q + return +} + +// Given the curve parameters, xP = x(P), computes xP = x([2^k]P) +// Safe to overlap xP, x2P. +func Pow2k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) { + var t0, t1 Fp2 + + x, z := &xP.X, &xP.Z + for i := uint32(0); i < k; i++ { + sub(&t0, x, z) // t0 = Xp - Zp + add(&t1, x, z) // t1 = Xp + Zp + sqr(&t0, &t0) // t0 = t0 ^ 2 + sqr(&t1, &t1) // t1 = t1 ^ 2 + mul(z, ¶ms.C, &t0) // Z2p = C24 * t0 + mul(x, z, &t1) // X2p = Z2p * t1 + sub(&t1, &t1, &t0) // t1 = t1 - t0 + mul(&t0, ¶ms.A, &t1) // t0 = A24+ * t1 + add(z, z, &t0) // Z2p = Z2p + t0 + mul(z, z, &t1) // Zp = Z2p * t1 + } +} + +// Given the curve parameters, xP = x(P), and k >= 0, compute xP = x([3^k]P). +// +// Safe to overlap xP, xR. +func Pow3k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) { + var t0, t1, t2, t3, t4, t5, t6 Fp2 + + x, z := &xP.X, &xP.Z + for i := uint32(0); i < k; i++ { + sub(&t0, x, z) // t0 = Xp - Zp + sqr(&t2, &t0) // t2 = t0^2 + add(&t1, x, z) // t1 = Xp + Zp + sqr(&t3, &t1) // t3 = t1^2 + add(&t4, &t1, &t0) // t4 = t1 + t0 + sub(&t0, &t1, &t0) // t0 = t1 - t0 + sqr(&t1, &t4) // t1 = t4^2 + sub(&t1, &t1, &t3) // t1 = t1 - t3 + sub(&t1, &t1, &t2) // t1 = t1 - t2 + mul(&t5, &t3, ¶ms.A) // t5 = t3 * A24+ + mul(&t3, &t3, &t5) // t3 = t5 * t3 + mul(&t6, &t2, ¶ms.C) // t6 = t2 * A24- + mul(&t2, &t2, &t6) // t2 = t2 * t6 + sub(&t3, &t2, &t3) // t3 = t2 - t3 + sub(&t2, &t5, &t6) // t2 = t5 - t6 + mul(&t1, &t2, &t1) // t1 = t2 * t1 + add(&t2, &t3, &t1) // t2 = t3 + t1 + sqr(&t2, &t2) // t2 = t2^2 + mul(x, &t2, &t4) // X3p = t2 * t4 + sub(&t1, &t3, &t1) // t1 = t3 - t1 + sqr(&t1, &t1) // t1 = t1^2 + mul(z, &t1, &t0) // Z3p = t1 * t0 + } +} + +// Set (y1, y2, y3) = (1/x1, 1/x2, 1/x3). +// +// All xi, yi must be distinct. +func Fp2Batch3Inv(x1, x2, x3, y1, y2, y3 *Fp2) { + var x1x2, t Fp2 + + mul(&x1x2, x1, x2) // x1*x2 + mul(&t, &x1x2, x3) // 1/(x1*x2*x3) + inv(&t, &t) + mul(y1, &t, x2) // 1/x1 + mul(y1, y1, x3) + mul(y2, &t, x1) // 1/x2 + mul(y2, y2, x3) + mul(y3, &t, &x1x2) // 1/x3 +} + +// Scalarmul3Pt is a right-to-left point multiplication that given the +// x-coordinate of P, Q and P-Q calculates the x-coordinate of R=Q+[scalar]P. +// nbits must be smaller or equal to len(scalar). +func ScalarMul3Pt(cparams *ProjectiveCurveParameters, P, Q, PmQ *ProjectivePoint, nbits uint, scalar []uint8) ProjectivePoint { + var R0, R2, R1 ProjectivePoint + aPlus2Over4 := CalcAplus2Over4(cparams) + R1 = *P + R2 = *PmQ + R0 = *Q + + // Iterate over the bits of the scalar, bottom to top + prevBit := uint8(0) + for i := uint(0); i < nbits; i++ { + bit := (scalar[i>>3] >> (i & 7) & 1) + swap := prevBit ^ bit + prevBit = bit + cswap(&R1.X, &R1.Z, &R2.X, &R2.Z, swap) + R0, R2 = xDbladd(&R0, &R2, &R1, &aPlus2Over4) + } + cswap(&R1.X, &R1.Z, &R2.X, &R2.Z, prevBit) + return R1 +} + +// Given a three-torsion point p = x(PB) on the curve E_(A:C), construct the +// three-isogeny phi : E_(A:C) -> E_(A:C)/ = E_(A':C'). +// +// Input: (XP_3: ZP_3), where P_3 has exact order 3 on E_A/C +// Output: * Curve coordinates (A' + 2C', A' - 2C') corresponding to E_A'/C' = A_E/C/ +// * Isogeny phi with constants in F_p^2 +func (phi *isogeny3) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv { + var t0, t1, t2, t3, t4 Fp2 + var coefEq CurveCoefficientsEquiv + var K1, K2 = &phi.K1, &phi.K2 + + sub(K1, &p.X, &p.Z) // K1 = XP3 - ZP3 + sqr(&t0, K1) // t0 = K1^2 + add(K2, &p.X, &p.Z) // K2 = XP3 + ZP3 + sqr(&t1, K2) // t1 = K2^2 + add(&t2, &t0, &t1) // t2 = t0 + t1 + add(&t3, K1, K2) // t3 = K1 + K2 + sqr(&t3, &t3) // t3 = t3^2 + sub(&t3, &t3, &t2) // t3 = t3 - t2 + add(&t2, &t1, &t3) // t2 = t1 + t3 + add(&t3, &t3, &t0) // t3 = t3 + t0 + add(&t4, &t3, &t0) // t4 = t3 + t0 + add(&t4, &t4, &t4) // t4 = t4 + t4 + add(&t4, &t1, &t4) // t4 = t1 + t4 + mul(&coefEq.C, &t2, &t4) // A24m = t2 * t4 + add(&t4, &t1, &t2) // t4 = t1 + t2 + add(&t4, &t4, &t4) // t4 = t4 + t4 + add(&t4, &t0, &t4) // t4 = t0 + t4 + mul(&t4, &t3, &t4) // t4 = t3 * t4 + sub(&t0, &t4, &coefEq.C) // t0 = t4 - A24m + add(&coefEq.A, &coefEq.C, &t0) // A24p = A24m + t0 + return coefEq +} + +// Given a 3-isogeny phi and a point pB = x(PB), compute x(QB), the x-coordinate +// of the image QB = phi(PB) of PB under phi : E_(A:C) -> E_(A':C'). +// +// The output xQ = x(Q) is then a point on the curve E_(A':C'); the curve +// parameters are returned by the GenerateCurve function used to construct phi. +func (phi *isogeny3) EvaluatePoint(p *ProjectivePoint) ProjectivePoint { + var t0, t1, t2 Fp2 + var q ProjectivePoint + var K1, K2 = &phi.K1, &phi.K2 + var px, pz = &p.X, &p.Z + + add(&t0, px, pz) // t0 = XQ + ZQ + sub(&t1, px, pz) // t1 = XQ - ZQ + mul(&t0, K1, &t0) // t2 = K1 * t0 + mul(&t1, K2, &t1) // t1 = K2 * t1 + add(&t2, &t0, &t1) // t2 = t0 + t1 + sub(&t0, &t1, &t0) // t0 = t1 - t0 + sqr(&t2, &t2) // t2 = t2 ^ 2 + sqr(&t0, &t0) // t0 = t0 ^ 2 + mul(&q.X, px, &t2) // XQ'= XQ * t2 + mul(&q.Z, pz, &t0) // ZQ'= ZQ * t0 + return q +} + +// Given a four-torsion point p = x(PB) on the curve E_(A:C), construct the +// four-isogeny phi : E_(A:C) -> E_(A:C)/ = E_(A':C'). +// +// Input: (XP_4: ZP_4), where P_4 has exact order 4 on E_A/C +// Output: * Curve coordinates (A' + 2C', 4C') corresponding to E_A'/C' = A_E/C/ +// * Isogeny phi with constants in F_p^2 +func (phi *isogeny4) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv { + var coefEq CurveCoefficientsEquiv + var xp4, zp4 = &p.X, &p.Z + var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3 + + sub(K2, xp4, zp4) + add(K3, xp4, zp4) + sqr(K1, zp4) + add(K1, K1, K1) + sqr(&coefEq.C, K1) + add(K1, K1, K1) + sqr(&coefEq.A, xp4) + add(&coefEq.A, &coefEq.A, &coefEq.A) + sqr(&coefEq.A, &coefEq.A) + return coefEq +} + +// Given a 4-isogeny phi and a point xP = x(P), compute x(Q), the x-coordinate +// of the image Q = phi(P) of P under phi : E_(A:C) -> E_(A':C'). +// +// Input: Isogeny returned by GenerateCurve and point q=(Qx,Qz) from E0_A/C +// Output: Corresponding point q from E1_A'/C', where E1 is 4-isogenous to E0 +func (phi *isogeny4) EvaluatePoint(p *ProjectivePoint) ProjectivePoint { + var t0, t1 Fp2 + var q = *p + var xq, zq = &q.X, &q.Z + var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3 + + add(&t0, xq, zq) + sub(&t1, xq, zq) + mul(xq, &t0, K2) + mul(zq, &t1, K3) + mul(&t0, &t0, &t1) + mul(&t0, &t0, K1) + add(&t1, xq, zq) + sub(zq, xq, zq) + sqr(&t1, &t1) + sqr(zq, zq) + add(xq, &t0, &t1) + sub(&t0, zq, &t0) + mul(xq, xq, &t1) + mul(zq, zq, &t0) + return q +} diff --git a/dh/sidh/internal/p503/curve_test.go b/dh/sidh/internal/p503/curve_test.go new file mode 100644 index 0000000..bf5b1d1 --- /dev/null +++ b/dh/sidh/internal/p503/curve_test.go @@ -0,0 +1,100 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p503 + +import ( + "bytes" + "testing" + + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +func vartimeEqProjFp2(lhs, rhs *ProjectivePoint) bool { + var t0, t1 Fp2 + mul(&t0, &lhs.X, &rhs.Z) + mul(&t1, &lhs.Z, &rhs.X) + return vartimeEqFp2(&t0, &t1) +} + +func toAffine(point *ProjectivePoint) *Fp2 { + var affineX Fp2 + inv(&affineX, &point.Z) + mul(&affineX, &affineX, &point.X) + return &affineX +} + +func Test_jInvariant(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var jbufRes = make([]byte, params.SharedSecretSize) + var jbufExp = make([]byte, params.SharedSecretSize) + var jInv Fp2 + + Jinvariant(&curve, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(jbufRes, &jInv, params.Bytelen) + + jInv = expectedJ + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(jbufExp, &jInv, params.Bytelen) + + if !bytes.Equal(jbufRes[:], jbufExp[:]) { + t.Error("Computed incorrect j-invariant: found\n", jbufRes, "\nexpected\n", jbufExp) + } +} + +func TestProjectivePointVartimeEq(t *testing.T) { + var xP ProjectivePoint + + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + xQ := xP + + // Scale xQ, which results in the same projective point + mul(&xQ.X, &xQ.X, &curveA) + mul(&xQ.Z, &xQ.Z, &curveA) + if !vartimeEqProjFp2(&xP, &xQ) { + t.Error("Expected the scaled point to be equal to the original") + } +} + +func TestPointMulVersusSage(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var cparams = CalcCurveParamsEquiv4(&curve) + var xP ProjectivePoint + + // x 2 + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow2k(&xP, &cparams, 1) + afxQ := toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP2) { + t.Error("\nExpected\n", affineXP2, "\nfound\n", afxQ) + } + + // x 4 + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow2k(&xP, &cparams, 2) + afxQ = toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP4) { + t.Error("\nExpected\n", affineXP4, "\nfound\n", afxQ) + } +} + +func TestPointMul9VersusSage(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var cparams = CalcCurveParamsEquiv3(&curve) + var xP ProjectivePoint + + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow3k(&xP, &cparams, 2) + afxQ := toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP9) { + t.Error("\nExpected\n", affineXP9, "\nfound\n", afxQ) + } +} + +func BenchmarkThreePointLadder(b *testing.B) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + for n := 0; n < b.N; n++ { + ScalarMul3Pt(&curve, &threePointLadderInputs[0], &threePointLadderInputs[1], &threePointLadderInputs[2], uint(len(scalar3Pt)*8), scalar3Pt[:]) + } +} diff --git a/dh/sidh/internal/p503/doc.go b/dh/sidh/internal/p503/doc.go new file mode 100644 index 0000000..3541a44 --- /dev/null +++ b/dh/sidh/internal/p503/doc.go @@ -0,0 +1,2 @@ +// Package p503 provides implementation of field arithmetic used in SIDH and SIKE. +package p503 diff --git a/dh/sidh/internal/p503/fp2.go b/dh/sidh/internal/p503/fp2.go new file mode 100644 index 0000000..089fdaa --- /dev/null +++ b/dh/sidh/internal/p503/fp2.go @@ -0,0 +1,195 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p503 + +import ( + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Montgomery multiplication. Input values must be already +// in Montgomery domain. +func mulP(dest, lhs, rhs *common.Fp) { + var ab common.FpX2 + mulP503(&ab, lhs, rhs) // = a*b*R*R + rdcP503(dest, &ab) // = a*b*R mod p +} + +// Set dest = x^((p-3)/4). If x is square, this is 1/sqrt(x). +// Uses variation of sliding-window algorithm from with window size +// of 5 and least to most significant bit sliding (left-to-right) +// See HAC 14.85 for general description. +// +// Allowed to overlap x with dest. +// All values in Montgomery domains +// Set dest = x^(2^k), for k >= 1, by repeated squarings. +func p34(dest, x *common.Fp) { + var lookup [16]common.Fp + + // This performs sum(powStrategy) + 1 squarings and len(lookup) + len(mulStrategy) + // multiplications. + powStrategy := []uint8{12, 5, 5, 2, 7, 11, 3, 8, 4, 11, 4, 7, 5, 6, 3, 7, 5, 7, 2, 12, 5, 6, 4, 6, 8, 6, 4, 7, 5, 5, 8, 5, 8, 5, 5, 8, 9, 3, 6, 2, 10, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3} + mulStrategy := []uint8{12, 11, 10, 0, 1, 8, 3, 7, 1, 8, 3, 6, 7, 14, 2, 14, 14, 9, 0, 13, 9, 15, 5, 12, 7, 13, 7, 15, 6, 7, 9, 0, 5, 7, 6, 8, 8, 3, 7, 0, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3} + initialMul := uint8(0) + + // Precompute lookup table of odd multiples of x for window + // size k=5. + var xx common.Fp + mulP(&xx, x, x) + lookup[0] = *x + for i := 1; i < 16; i++ { + mulP(&lookup[i], &lookup[i-1], &xx) + } + + // Now lookup = {x, x^3, x^5, ... } + // so that lookup[i] = x^{2*i + 1} + // so that lookup[k/2] = x^k, for odd k + *dest = lookup[initialMul] + for i := uint8(0); i < uint8(len(powStrategy)); i++ { + mulP(dest, dest, dest) + for j := uint8(1); j < powStrategy[i]; j++ { + mulP(dest, dest, dest) + } + mulP(dest, dest, &lookup[mulStrategy[i]]) + } +} + +func add(dest, lhs, rhs *common.Fp2) { + addP503(&dest.A, &lhs.A, &rhs.A) + addP503(&dest.B, &lhs.B, &rhs.B) +} + +func sub(dest, lhs, rhs *common.Fp2) { + subP503(&dest.A, &lhs.A, &rhs.A) + subP503(&dest.B, &lhs.B, &rhs.B) +} + +func mul(dest, lhs, rhs *common.Fp2) { + var bMinA, cMinD common.Fp + var ac, bd common.FpX2 + var adPlusBc common.FpX2 + var acMinBd common.FpX2 + + // Let (a,b,c,d) = (lhs.a,lhs.b,rhs.a,rhs.b). + // + // (a + bi)*(c + di) = (a*c - b*d) + (a*d + b*c)i + // + // Use Karatsuba's trick: note that + // + // (b - a)*(c - d) = (b*c + a*d) - a*c - b*d + // + // so (a*d + b*c) = (b-a)*(c-d) + a*c + b*d. + mulP503(&ac, &lhs.A, &rhs.A) // = a*c*R*R + mulP503(&bd, &lhs.B, &rhs.B) // = b*d*R*R + subP503(&bMinA, &lhs.B, &lhs.A) // = (b-a)*R + subP503(&cMinD, &rhs.A, &rhs.B) // = (c-d)*R + mulP503(&adPlusBc, &bMinA, &cMinD) // = (b-a)*(c-d)*R*R + adlP503(&adPlusBc, &adPlusBc, &ac) // = ((b-a)*(c-d) + a*c)*R*R + adlP503(&adPlusBc, &adPlusBc, &bd) // = ((b-a)*(c-d) + a*c + b*d)*R*R + rdcP503(&dest.B, &adPlusBc) // = (a*d + b*c)*R mod p + sulP503(&acMinBd, &ac, &bd) // = (a*c - b*d)*R*R + rdcP503(&dest.A, &acMinBd) // = (a*c - b*d)*R mod p +} + +// Set dest = 1/x +// +// Allowed to overlap dest with x. +// +// Returns dest to allow chaining operations. +func inv(dest, x *common.Fp2) { + var e1, e2 common.FpX2 + var f1, f2 common.Fp + + // We want to compute + // + // 1 1 (a - bi) (a - bi) + // -------- = -------- -------- = ----------- + // (a + bi) (a + bi) (a - bi) (a^2 + b^2) + // + // Letting c = 1/(a^2 + b^2), this is + // + // 1/(a+bi) = a*c - b*ci. + + mulP503(&e1, &x.A, &x.A) // = a*a*R*R + mulP503(&e2, &x.B, &x.B) // = b*b*R*R + adlP503(&e1, &e1, &e2) // = (a^2 + b^2)*R*R + rdcP503(&f1, &e1) // = (a^2 + b^2)*R mod p + // Now f1 = a^2 + b^2 + + mulP(&f2, &f1, &f1) + p34(&f2, &f2) + mulP(&f2, &f2, &f2) + mulP(&f2, &f2, &f1) + + mulP503(&e1, &x.A, &f2) + rdcP503(&dest.A, &e1) + + subP503(&f1, &common.Fp{}, &x.B) + mulP503(&e1, &f1, &f2) + rdcP503(&dest.B, &e1) +} + +func sqr(dest, x *common.Fp2) { + var a2, aPlusB, aMinusB common.Fp + var a2MinB2, ab2 common.FpX2 + + a := &x.A + b := &x.B + + // (a + bi)*(a + bi) = (a^2 - b^2) + 2abi. + addP503(&a2, a, a) // = a*R + a*R = 2*a*R + addP503(&aPlusB, a, b) // = a*R + b*R = (a+b)*R + subP503(&aMinusB, a, b) // = a*R - b*R = (a-b)*R + mulP503(&a2MinB2, &aPlusB, &aMinusB) // = (a+b)*(a-b)*R*R = (a^2 - b^2)*R*R + mulP503(&ab2, &a2, b) // = 2*a*b*R*R + rdcP503(&dest.A, &a2MinB2) // = (a^2 - b^2)*R mod p + rdcP503(&dest.B, &ab2) // = 2*a*b*R mod p +} + +// In case choice == 1, performs following swap in constant time: +// xPx <-> xQx +// xPz <-> xQz +// Otherwise returns xPx, xPz, xQx, xQz unchanged +func cswap(xPx, xPz, xQx, xQz *common.Fp2, choice uint8) { + cswapP503(&xPx.A, &xQx.A, choice) + cswapP503(&xPx.B, &xQx.B, choice) + cswapP503(&xPz.A, &xQz.A, choice) + cswapP503(&xPz.B, &xQz.B, choice) +} + +// Converts in.A and in.B to Montgomery domain and stores +// in 'out' +// out.A = in.A * R mod p +// out.B = in.B * R mod p +// Performs v = v*R^2*R^(-1) mod p, for both in.A and in.B +func ToMontgomery(out, in *common.Fp2) { + var aRR common.FpX2 + + // a*R*R + mulP503(&aRR, &in.A, &P503R2) + // a*R mod p + rdcP503(&out.A, &aRR) + mulP503(&aRR, &in.B, &P503R2) + rdcP503(&out.B, &aRR) +} + +// Converts in.A and in.B from Montgomery domain and stores +// in 'out' +// out.A = in.A mod p +// out.B = in.B mod p +// +// After returning from the call 'in' is not modified. +func FromMontgomery(out, in *common.Fp2) { + var aR common.FpX2 + + // convert from montgomery domain + copy(aR[:], in.A[:]) + rdcP503(&out.A, &aR) // = a mod p in [0, 2p) + modP503(&out.A) // = a mod p in [0, p) + for i := range aR { + aR[i] = 0 + } + copy(aR[:], in.B[:]) + rdcP503(&out.B, &aR) + modP503(&out.B) +} diff --git a/dh/sidh/internal/p503/fp2_test.go b/dh/sidh/internal/p503/fp2_test.go new file mode 100644 index 0000000..3e15994 --- /dev/null +++ b/dh/sidh/internal/p503/fp2_test.go @@ -0,0 +1,245 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p503 + +import ( + "math/rand" + "reflect" + "testing" + "testing/quick" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +type testParams struct { + Point common.ProjectivePoint + Cparam common.ProjectiveCurveParameters + ExtElem common.Fp2 +} + +// Returns true if lhs = rhs. Takes variable time. +func vartimeEqFp2(lhs, rhs *common.Fp2) bool { + a := *lhs + b := *rhs + + modP503(&a.A) + modP503(&a.B) + modP503(&b.A) + modP503(&b.B) + + eq := true + for i := 0; i < FpWords && eq; i++ { + eq = eq && (a.A[i] == b.A[i]) + eq = eq && (a.B[i] == b.B[i]) + } + return eq +} + +func (testParams) generateFp2(rand *rand.Rand) common.Fp2 { + // Generation strategy: low limbs taken from [0,2^64); high limb + // taken from smaller range + // + // Size hint is ignored since all elements are fixed size. + // + // Field elements taken in range [0,2p). Emulate this by capping + // the high limb by the top digit of 2*p-1: + // + // sage: (2*p-1).digits(2^64)[-1] + // + // This still allows generating values >= 2p, but hopefully that + // excess is OK (and if it's not, we'll find out, because it's for + // testing...) + highLimb := rand.Uint64() % P503x2[FpWords-1] + fpElementGen := func() (fp common.Fp) { + for i := 0; i < (FpWords - 1); i++ { + fp[i] = rand.Uint64() + } + fp[FpWords-1] = highLimb + return fp + } + return common.Fp2{A: fpElementGen(), B: fpElementGen()} +} + +func (c testParams) Generate(rand *rand.Rand, size int) reflect.Value { + return reflect.ValueOf( + testParams{ + common.ProjectivePoint{ + X: c.generateFp2(rand), + Z: c.generateFp2(rand), + }, + common.ProjectiveCurveParameters{ + A: c.generateFp2(rand), + C: c.generateFp2(rand), + }, + c.generateFp2(rand), + }) +} + +func TestOne(t *testing.T) { + var tmp common.Fp2 + + mul(&tmp, ¶ms.OneFp2, ¶ms.A.AffineP) + if !vartimeEqFp2(&tmp, ¶ms.A.AffineP) { + t.Error("Not equal 1") + } +} + +func TestFp2ToBytesRoundTrip(t *testing.T) { + roundTrips := func(x testParams) bool { + var xBytes = make([]byte, 2*params.Bytelen) + var xPrime common.Fp2 + + common.Fp2ToBytes(xBytes[:], &x.ExtElem, params.Bytelen) + common.BytesToFp2(&xPrime, xBytes[:], params.Bytelen) + return vartimeEqFp2(&xPrime, &x.ExtElem) + } + + if err := quick.Check(roundTrips, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2MulDistributesOverAdd(t *testing.T) { + mulDistributesOverAdd := func(x, y, z testParams) bool { + // Compute t1 = (x+y)*z + t1 := new(common.Fp2) + add(t1, &x.ExtElem, &y.ExtElem) + mul(t1, t1, &z.ExtElem) + + // Compute t2 = x*z + y*z + t2 := new(common.Fp2) + t3 := new(common.Fp2) + mul(t2, &x.ExtElem, &z.ExtElem) + mul(t3, &y.ExtElem, &z.ExtElem) + add(t2, t2, t3) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(mulDistributesOverAdd, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2MulIsAssociative(t *testing.T) { + isAssociative := func(x, y, z testParams) bool { + // Compute t1 = (x*y)*z + t1 := new(common.Fp2) + mul(t1, &x.ExtElem, &y.ExtElem) + mul(t1, t1, &z.ExtElem) + + // Compute t2 = (y*z)*x + t2 := new(common.Fp2) + mul(t2, &y.ExtElem, &z.ExtElem) + mul(t2, t2, &x.ExtElem) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(isAssociative, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2SquareMatchesMul(t *testing.T) { + sqrMatchesMul := func(x testParams) bool { + // Compute t1 = (x*x) + t1 := new(common.Fp2) + mul(t1, &x.ExtElem, &x.ExtElem) + + // Compute t2 = x^2 + t2 := new(common.Fp2) + sqr(t2, &x.ExtElem) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(sqrMatchesMul, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2Inv(t *testing.T) { + inverseIsCorrect := func(x testParams) bool { + z := new(common.Fp2) + inv(z, &x.ExtElem) + + // Now z = (1/x), so (z * x) * x == x + mul(z, z, &x.ExtElem) + mul(z, z, &x.ExtElem) + + return vartimeEqFp2(z, &x.ExtElem) + } + + // This is more expensive; run fewer tests + var quickCheckConfig = &quick.Config{MaxCount: (1 << 11)} + if err := quick.Check(inverseIsCorrect, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2Batch3Inv(t *testing.T) { + batchInverseIsCorrect := func(x1, x2, x3 testParams) bool { + var x1Inv, x2Inv, x3Inv common.Fp2 + inv(&x1Inv, &x1.ExtElem) + inv(&x2Inv, &x2.ExtElem) + inv(&x3Inv, &x3.ExtElem) + + var y1, y2, y3 common.Fp2 + Fp2Batch3Inv(&x1.ExtElem, &x2.ExtElem, &x3.ExtElem, &y1, &y2, &y3) + + return (vartimeEqFp2(&x1Inv, &y1) && vartimeEqFp2(&x2Inv, &y2) && vartimeEqFp2(&x3Inv, &y3)) + } + + // This is more expensive; run fewer tests + var quickCheckConfig = &quick.Config{MaxCount: (1 << 8)} + if err := quick.Check(batchInverseIsCorrect, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func BenchmarkFp2Mul(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + mul(w, z, z) + } +} + +func BenchmarkFp2Inv(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + inv(w, z) + } +} + +func BenchmarkFp2Square(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + sqr(w, z) + } +} + +func BenchmarkFp2Add(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + add(w, z, z) + } +} + +func BenchmarkFp2Sub(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + sub(w, z, z) + } +} diff --git a/dh/sidh/internal/p503/params.go b/dh/sidh/internal/p503/params.go new file mode 100644 index 0000000..432ac50 --- /dev/null +++ b/dh/sidh/internal/p503/params.go @@ -0,0 +1,203 @@ +package p503 + +//go:generate go run ../templates/gen.go P503 + +import ( + "github.com/henrydcase/nobs/dh/sidh/internal/common" + "golang.org/x/sys/cpu" +) + +const ( + // Number of uint64 limbs used to store field element + FpWords = 8 +) + +// P503 is a prime used by field Fp503 +var ( + // According to https://github.com/golang/go/issues/28230, + // variables referred from the assembly must be in the same package. + // HasBMI2 signals support for MULX which is in BMI2 + HasBMI2 = cpu.X86.HasBMI2 + // HasADXandBMI2 signals support for ADX and BMI2 + HasADXandBMI2 = cpu.X86.HasBMI2 && cpu.X86.HasADX + + // P503 is a prime used by field Fp503 + P503 = common.Fp{ + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xABFFFFFFFFFFFFFF, + 0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E, + } + + // P503x2 = 2*p503 - 1 + P503x2 = common.Fp{ + 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x57FFFFFFFFFFFFFF, + 0x2610B7B44423CF41, 0x3737ED90F6FCFB5E, 0xC08B8D7BB4EF49A0, 0x0080CDEA83023C3C, + } + + // P503p1 = p503 + 1 + P503p1 = common.Fp{ + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xAC00000000000000, + 0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E, + } + + // P503R2 = (2^512)^2 mod p + P503R2 = common.Fp{ + 0x5289A0CF641D011F, 0x9B88257189FED2B9, 0xA3B365D58DC8F17A, 0x5BC57AB6EFF168EC, + 0x9E51998BD84D4423, 0xBF8999CBAC3B5695, 0x46E9127BCE14CDB6, 0x003F6CFCE8B81771, + } + + // P503p1s8 = p503 + 1 left-shifted by 8, assuming little endianness + P503p1s8 = common.Fp{ + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x085BDA2211E7A0AC, 0x9BF6C87B7E7DAF13, 0x45C6BDDA77A4D01B, 0x4066F541811E1E60, + } + + // P503p1Zeros number of 0 digits in the least significant part of P503+1 + P503p1Zeros = 3 + + // 1*R mod p + one = common.Fp2{ + A: common.Fp{ + 0x00000000000003F9, 0x0000000000000000, 0x0000000000000000, 0xB400000000000000, + 0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x0026FBAEC60F5953}, + } + // 1/2 * R mod p + half = common.Fp2{ + A: common.Fp{ + 0x00000000000001FC, 0x0000000000000000, 0x0000000000000000, 0xB000000000000000, + 0x3B69BB2464785D2A, 0x36824A2AF0FE9896, 0xF5899F427A94F309, 0x0033B15203C83BB8}, + } + // 6*R mod p + six = common.Fp2{ + A: common.Fp{ + 0x00000000000017D8, 0x0000000000000000, 0x0000000000000000, 0xE000000000000000, + 0x30B1E6E3A51520FA, 0xB13BC3BF6FFB3992, 0x8045412EEB3E3DED, 0x0069182E2159DBB8}, + } + + params = common.SidhParams{ + ID: common.Fp503, + // SIDH public key byte size. + PublicKeySize: 378, + // SIDH shared secret byte size. + SharedSecretSize: 126, + A: common.DomainParams{ + // The x-coordinate of PA + AffineP: common.Fp2{ + A: common.Fp{ + 0x5D083011589AD893, 0xADFD8D2CB67D0637, 0x330C9AC34FFB6361, 0xF0D47489A2E805A2, + 0x27E2789259C6B8DC, 0x63866A2C121931B9, 0x8D4C65A7137DCF44, 0x003A183AE5967B3F, + }, + B: common.Fp{ + 0x7E3541B8C96D1519, 0xD3ADAEEC0D61A26C, 0xC0A2219CE7703DD9, 0xFF3E46658FCDBC52, + 0xD5B38DEAE6E196FF, 0x1AAC826364956D58, 0xEC9F4875B9A5F27A, 0x001B0B475AB99843, + }, + }, + // The x-coordinate of QA + AffineQ: common.Fp2{ + A: common.Fp{ + 0x4D83695107D03BAD, 0x221F3299005E2FCF, 0x78E6AE22F30DECF2, 0x6D982DB5111253E4, + 0x504C80A8AB4526A8, 0xEFD0C3AA210BB024, 0xCB77483501DC6FCF, 0x001052544A96BDF3, + }, + B: common.Fp{ + 0x0D74FE3402BCAE47, 0xDF5B8CDA832D8AED, 0xB86BCF06E4BD837E, 0x892A2933A0FA1F63, + 0x9F88FC67B6CCB461, 0x822926EA9DDA3AC8, 0xEAC8DDE5855425ED, 0x000618FE6DA37A80, + }, + }, + + // The x-coordinate of RA = PA-QA + AffineR: common.Fp2{ + A: common.Fp{ + 0x1D9D32D2DC877C17, 0x5517CD8F71D5B02B, 0x395AFB8F6B60C117, 0x3AE31AC85F9098C8, + 0x5F5341C198450848, 0xF8C609DBEA435C6A, 0xD832BC7EDC7BA5E4, 0x002AD98AA6968BF5, + }, + B: common.Fp{ + 0xC466CAB0F73C2E5B, 0x7B1817148FB2CF9C, 0x873E87C099E470A0, 0xBB17AC6D17A7BAC1, + 0xA146FDCD0F2E2A58, 0x88B311E9CEAB6201, 0x37604CF5C7951757, 0x0006804071C74BF9, + }, + }, + // Max size of secret key for 2-torsion group, corresponds to 2^e2 - 1 + SecretBitLen: 250, + // SecretBitLen in bytes. + SecretByteLen: 32, + // 2-torsion group computation strategy + IsogenyStrategy: []uint32{ + 0x3D, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, + 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, + 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x1D, 0x10, 0x08, 0x04, 0x02, 0x01, + 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x0D, 0x08, + 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x05, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01}, + }, + B: common.DomainParams{ + // The x-coordinate of PB + AffineP: common.Fp2{ + A: common.Fp{ + 0xDF630FC5FB2468DB, 0xC30C5541C102040E, 0x3CDC9987B76511FC, 0xF54B5A09353D0CDD, + 0x3ADBA8E00703C42F, 0x8253F9303DDC95D0, 0x62D30778763ABFD7, 0x001CD00FB581CD55, + }, + B: common.Fp{ + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + }, + }, + // The x-coordinate of QB + AffineQ: common.Fp2{ + A: common.Fp{ + 0x2E3457A12B429261, 0x311F94E89627DCF8, 0x5B71C98FD1DB73F6, 0x3671DB7DCFC21541, + 0xB6D1484C9FE0CF4F, 0x19CD110717356E35, 0xF4F9FB00AC9919DF, 0x0035BC124D38A70B, + }, + B: common.Fp{ + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + }, + }, + // The x-coordinate of RB = PB - QB + AffineR: common.Fp2{ + A: common.Fp{ + 0x2E08BB99413D2952, 0xD3021467CD088D72, 0x21017AF859752245, 0x26314ED8FFD9DE5C, + 0x4AF43C73344B6686, 0xCFA1F91149DF0993, 0xF327A95365587A89, 0x000DBF54E03D3906, + }, + B: common.Fp{ + 0x03E03FF342F5F304, 0x993D604D7B4B6E56, 0x80412F4D9280E71F, 0x0FFDC9EF990B3982, + 0xE584E64C51604931, 0x1374F42AC8B0BBD7, 0x07D5BC37DFA41A5F, 0x00396CCFD61FD34C, + }, + }, + // Size of secret key for 3-torsion group, corresponds to log_2(3^e3) - 1. + SecretBitLen: 252, + // SecretBitLen in bytes. + SecretByteLen: 32, + // 3-torsion group computation strategy + IsogenyStrategy: []uint32{ + 0x47, 0x26, 0x15, 0x0D, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x05, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, + 0x01, 0x01, 0x01, 0x09, 0x05, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x11, 0x09, 0x05, 0x03, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, + 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, + 0x01, 0x02, 0x01, 0x01, 0x21, 0x11, 0x09, 0x05, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, + 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, + 0x01, 0x02, 0x01, 0x01}, + }, + OneFp2: one, + HalfFp2: half, + MsgLen: 24, + // SIKEp503 provides 192 bit of classical security ([SIKE], 5.1) + KemSize: 24, + // ceil(503+7/8) + Bytelen: 63, + CiphertextSize: 24 + 378, + InitCurve: common.ProjectiveCurveParameters{ + A: six, + C: one, + }, + } +) + +func init() { + common.Register(common.Fp503, ¶ms) +} diff --git a/dh/sidh/internal/p503/params_test.go b/dh/sidh/internal/p503/params_test.go new file mode 100644 index 0000000..d174613 --- /dev/null +++ b/dh/sidh/internal/p503/params_test.go @@ -0,0 +1,73 @@ +package p503 + +// Contains values used by tests +import ( + "testing/quick" + + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Values omputed using Sage +var ( + // j = 3674553797500778604587777859668542828244523188705960771798425843588160903687122861541242595678107095655647237100722594066610650373491179241544334443939077738732728884873568393760629500307797547379838602108296735640313894560419*i + 3127495302417548295242630557836520229396092255080675419212556702820583041296798857582303163183558315662015469648040494128968509467224910895884358424271180055990446576645240058960358037224785786494172548090318531038910933793845 + expectedJ = Fp2{ + A: Fp{0x2c441d03b72e27c, 0xf2c6748151dbf84, 0x3a774f6191070e, 0xa7c6212c9c800ba6, 0x23921b5cf09abc27, 0x9e1baefbb3cd4265, 0x8cd6a289f12e10dc, 0x3fa364128cf87e}, + B: Fp{0xe7497ac2bf6b0596, 0x629ee01ad23bd039, 0x95ee11587a119fa7, 0x572fb28a24772269, 0x3c00410b6c71567e, 0xe681e83a345f8a34, 0x65d21b1d96bd2d52, 0x7889a47e58901}, + } + + // A = 8752234765512331234913716743014562460822083005386252003333602919474238975785850965349950219277942402920758585086620525443539725921333735154674119646075*i + 6339624979889725406021454983012408976766782818694212228554611573314701271183857175866122275755278397694585249002282183018114967373119429936587424396917 + curveA = Fp2{ + A: Fp{0xd9816986a543095f, 0xa78cb1d7217bec21, 0x9595dc97b74ea70, 0x9120a1da6b42797d, 0x59ef9d903f74e47c, 0x4c58a4cdc45b6d0b, 0x816d5213aaf7ee6d, 0x3892fee6bb7343}, + B: Fp{0x28c5288acbedf11b, 0x2143a438c86f6c68, 0x7cb5c4ae9c4c8e34, 0xb478aea445eed48b, 0x24d5c175776db478, 0x234582f8676c0ebe, 0x56234267b625fb08, 0x2c6e58d84b1192}} + + // C = 10458464853790890798085664692909194316288127038910691163573355876336993883402795907795767791362493831987298578966325154262747805705783782806176495638177*i + 7770984753616185271325854825309278833018655051139367603077592443785629339985729818288672809062782315510526648882226172896710704020683893684611137718845 + curveC = Fp2{ + A: Fp{0xe05948236f2f913b, 0xc45da9ad1219a255, 0x7a568972a32fc1d0, 0x30f00bdd7071c3b1, 0x3b761b8dac2c98bc, 0x760f21b2179737b6, 0x13217e6656a13476, 0x2606b798e685aa}, + B: Fp{0x1c0171f78820052e, 0x440b7f7087e57140, 0xe0510c07b31b0e96, 0xd0cf489b2ac4aea9, 0x4fb328f1c1fdf783, 0xb3b4912342951cb7, 0x70a4b64e81961c42, 0x33eed63cf07181}} + // x(P) = 9720237205826983370867050298878715935679372786589878620121159082290288918688002583435964840822877971257659901481591644347943354235932355923042390796255*i + 634577413124118560098123299804750904956499531431297942628887930019161512075536652691244843248133437326050395005054997679717801535474938466995392156605 + affineXP = Fp2{ + A: Fp{0xb606d954d407faf2, 0x58a1ef6cd213a203, 0x9823b55033e62f7b, 0x59cafc060d5e25a1, 0x529685f1753526fc, 0xc2eac3d219989c7d, 0xc5e30c75dfd343a0, 0x378285adc968a0}, + B: Fp{0x6670f36db977b9da, 0xa07e2fdda5e1a7f0, 0xf367a7a722aed87d, 0x6c269e06d595cd10, 0x8379aa6092d87700, 0x57276ce3557ee7ae, 0xac8107bfbcd28993, 0x3d6f98869617a7}} + + affineXP2 = Fp2{ + A: Fp{0x4e1133c2b3855902, 0x875a775c67597fbb, 0xd17eb74254141abb, 0x1d5a464a4f3391f5, 0x24405c332811d007, 0x7e47e3eb489a7372, 0x65b130dfd9efe605, 0xfa69fac179803}, + B: Fp{0x329f5322e1be51ee, 0x9004dca8132ebd6f, 0x7cd87e447ca8a7b6, 0x10a6ec02c38ce69e, 0x8cef2ed7d112ac46, 0x5f385a9fc4b57cd7, 0x68a366354fe7a32e, 0x2223c1455486ac}} + + affineXP4 = Fp2{ + A: Fp{0x4eb695d34b46be8f, 0xfb5e76c58585f2d2, 0xa41f8aafa6dbb531, 0x4db82f5db5cfd144, 0x14dab0e3200cbba0, 0x430381706a279f81, 0xdf6707a57161f81, 0x44740f17197c3}, + B: Fp{0xa2473705cdb6d4e9, 0xfa3cd67b9c15502c, 0xf0928166d0c5cee1, 0x6150aba0c874faaa, 0x6c0b18d6d92f9034, 0xcff71d340fc1e72e, 0x19a47027af917587, 0x25ed4bad443b8f}} + + affineXP9 = Fp2{ + A: Fp{0x112da30e288217e0, 0x5b336d527320a5f7, 0xbbf4d9403b68e3c6, 0x55eccb31c40b359c, 0x8907129ab69b3203, 0x69cc8c750125a915, 0xa41a38e6f530c0e1, 0xbe68e23af1b8d}, + B: Fp{0x472c603765964213, 0xe4e64995b0769754, 0x4515583c74a6dd24, 0xff7c57f5818363a2, 0xbeaeb24662a92177, 0x8a54fa61fbf24c68, 0xa85542049eb45e12, 0x2b54caf655e285}} + + // Inputs for testing 3-point-ladder + threePointLadderInputs = []ProjectivePoint{ + // x(P) + { + X: Fp2{ + A: Fp{0x43941FA9244C059E, 0xD1F337D076941189, 0x6B6A8B3A8763C96A, 0x6DF569708D6C9482, 0x487EE5707A52F4AA, 0xDE396F6E2559689E, 0xE5EE3895A8991469, 0x2B0946695790A8}, + B: Fp{0xAB552C0FDAED092E, 0x7DF895E43E7DCB1C, 0x35C700E761920C4B, 0xCC5807DD70DC117A, 0x0884039A5A8DB18A, 0xD04620B3D0738052, 0xA200835605138F10, 0x3FF2E59B2FDC6A}}, + Z: params.OneFp2, + }, + // x(Q) + { + X: Fp2{ + A: Fp{0x77015826982BA1FD, 0x44024489673471E4, 0x1CAA2A5F4D5DA63B, 0xA183C07E50738C01, 0x8B97782D4E1A0DE6, 0x9B819522FBC38280, 0x0BDA46A937FB7B8A, 0x3B3614305914DF}, + B: Fp{0xBF0366E97B3168D9, 0xAA522AC3879CEF0F, 0x0AF5EC975BD035C8, 0x1F26FEE7BBAC165C, 0xA0EE6A637724A6AB, 0xFB52101E36BA3A38, 0xD29CF5E376E17376, 0x1374A50DF57071}}, + Z: params.OneFp2, + }, + // x(P-Q) + { + X: Fp2{ + A: Fp{0xD99279BBD41EA559, 0x35CF18E72F578214, 0x90473B1DC77F73E8, 0xBFFEA930B25D7F66, 0xFD558EA177B900B2, 0x7CFAD273A782A23E, 0x6B1F610822E0F611, 0x26D2D2EF9619B5}, + B: Fp{0x534F83651CBCC75D, 0x591FB4757AED5D08, 0x0B04353D40BED542, 0x829A94703AAC9139, 0x0F9C2E6D7663EB5B, 0x5D2D0F90C283F746, 0x34C872AA12A7676E, 0x0ECDB605FBFA16}}, + Z: params.OneFp2, + }, + } + scalar3Pt = [...]uint8{0x9f, 0x3b, 0xe7, 0xf9, 0xf4, 0x7c, 0xe6, 0xce, 0x79, 0x3e, 0x3d, 0x9f, 0x9f, 0x3b, 0xe7, 0xf9, 0xf4, 0x7c, 0xe6, 0xce, 0x79, 0x3e, 0x3d, 0x9f} +) + +var quickCheckConfig = &quick.Config{ + MaxCount: (1 << 15), +} diff --git a/dh/sidh/p751/arith_amd64.s b/dh/sidh/internal/p751/arith_amd64.s similarity index 93% rename from dh/sidh/p751/arith_amd64.s rename to dh/sidh/internal/p751/arith_amd64.s index 1693a08..2ae2094 100644 --- a/dh/sidh/p751/arith_amd64.s +++ b/dh/sidh/internal/p751/arith_amd64.s @@ -39,7 +39,7 @@ #define REG_P2 SI #define REG_P3 DX -TEXT ·fp751StrongReduce(SB), NOSPLIT, $0-8 +TEXT ·modP751(SB), NOSPLIT, $0-8 MOVQ x+0(FP), REG_P1 // Zero AX for later use: @@ -98,55 +98,137 @@ TEXT ·fp751StrongReduce(SB), NOSPLIT, $0-8 RET -TEXT ·fp751ConditionalSwap(SB), NOSPLIT, $0-17 +TEXT ·cswapP751(SB), NOSPLIT, $0-17 MOVQ x+0(FP), REG_P1 MOVQ y+8(FP), REG_P2 - MOVBLZX choice+16(FP), AX // AL = 0 or 1 + MOVB choice+16(FP), AL // AL = 0 or 1 + MOVBLZX AL, AX // AX = 0 or 1 + NEGQ AX // RAX = 0x00..00 or 0xff..ff - // Make AX, so that either all bits are set or non - // AX = 0 or 1 - NEGQ AX + MOVQ (0*8)(REG_P1), BX // BX = x[0] + MOVQ (0*8)(REG_P2), CX // CX = y[0] + MOVQ CX, DX // DX = y[0] + XORQ BX, DX // DX = y[0] ^ x[0] + ANDQ AX, DX // DX = (y[0] ^ x[0]) & mask + XORQ DX, BX // BX = (y[0] ^ x[0]) & mask) ^ x[0] = x[0] or y[0] + XORQ DX, CX // CX = (y[0] ^ x[0]) & mask) ^ y[0] = y[0] or x[0] + MOVQ BX, (0*8)(REG_P1) + MOVQ CX, (0*8)(REG_P2) - // Fill xmm15. After this step first half of XMM15 is - // just zeros and second half is whatever in AX - MOVQ AX, X15 + MOVQ (1*8)(REG_P1), BX + MOVQ (1*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (1*8)(REG_P1) + MOVQ CX, (1*8)(REG_P2) - // Copy lower double word everywhere else. So that - // XMM15=AL|AL|AL|AL. As AX has either all bits set - // or non result will be that XMM15 has also either - // all bits set or non of them. - PSHUFD $0, X15, X15 + MOVQ (2*8)(REG_P1), BX + MOVQ (2*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (2*8)(REG_P1) + MOVQ CX, (2*8)(REG_P2) -#ifndef CSWAP_BLOCK -#define CSWAP_BLOCK(idx) \ - MOVOU (idx*16)(REG_P1), X0 \ - MOVOU (idx*16)(REG_P2), X1 \ - \ // X2 = mask & (X0 ^ X1) - MOVO X1, X2 \ - PXOR X0, X2 \ - PAND X15, X2 \ - \ - PXOR X2, X0 \ - PXOR X2, X1 \ - \ - MOVOU X0, (idx*16)(REG_P1) \ - MOVOU X1, (idx*16)(REG_P2) -#endif + MOVQ (3*8)(REG_P1), BX + MOVQ (3*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (3*8)(REG_P1) + MOVQ CX, (3*8)(REG_P2) - CSWAP_BLOCK(0) - CSWAP_BLOCK(1) - CSWAP_BLOCK(2) - CSWAP_BLOCK(3) - CSWAP_BLOCK(4) - CSWAP_BLOCK(5) + MOVQ (4*8)(REG_P1), BX + MOVQ (4*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (4*8)(REG_P1) + MOVQ CX, (4*8)(REG_P2) + + MOVQ (5*8)(REG_P1), BX + MOVQ (5*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (5*8)(REG_P1) + MOVQ CX, (5*8)(REG_P2) + + MOVQ (6*8)(REG_P1), BX + MOVQ (6*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (6*8)(REG_P1) + MOVQ CX, (6*8)(REG_P2) + + MOVQ (7*8)(REG_P1), BX + MOVQ (7*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (7*8)(REG_P1) + MOVQ CX, (7*8)(REG_P2) + + MOVQ (8*8)(REG_P1), BX + MOVQ (8*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (8*8)(REG_P1) + MOVQ CX, (8*8)(REG_P2) + + MOVQ (9*8)(REG_P1), BX + MOVQ (9*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (9*8)(REG_P1) + MOVQ CX, (9*8)(REG_P2) + + MOVQ (10*8)(REG_P1), BX + MOVQ (10*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (10*8)(REG_P1) + MOVQ CX, (10*8)(REG_P2) + + MOVQ (11*8)(REG_P1), BX + MOVQ (11*8)(REG_P2), CX + MOVQ CX, DX + XORQ BX, DX + ANDQ AX, DX + XORQ DX, BX + XORQ DX, CX + MOVQ BX, (11*8)(REG_P1) + MOVQ CX, (11*8)(REG_P2) -#ifdef CSWAP_BLOCK -#undef CSWAP_BLOCK -#endif RET -TEXT ·fp751AddReduced(SB), NOSPLIT, $0-24 +TEXT ·addP751(SB), NOSPLIT, $0-24 MOVQ z+0(FP), REG_P3 MOVQ x+8(FP), REG_P1 @@ -277,7 +359,7 @@ TEXT ·fp751AddReduced(SB), NOSPLIT, $0-24 RET -TEXT ·fp751SubReduced(SB), NOSPLIT, $0-24 +TEXT ·subP751(SB), NOSPLIT, $0-24 MOVQ z+0(FP), REG_P3 MOVQ x+8(FP), REG_P1 @@ -380,7 +462,7 @@ TEXT ·fp751SubReduced(SB), NOSPLIT, $0-24 RET -TEXT ·fp751Mul(SB), $96-24 +TEXT ·mulP751(SB), $96-24 // Here we store the destination in CX instead of in REG_P3 because the // multiplication instructions use DX as an implicit destination @@ -1536,7 +1618,7 @@ TEXT ·fp751Mul(SB), $96-24 // Output: OUT 768-bit #define REDC(C, M0, MULS) \ \ // a[0-3] x p751p1_nz --> result: [reg_p2+48], [reg_p2+56], [reg_p2+64], and rbp, r8:r14 - MULS(M0, ·p751p1, 48+C, R8, R9, R13, R10, R14, R12, R11, BP, BX, CX, R15) \ + MULS(M0, ·P751p1, 48+C, R8, R9, R13, R10, R14, R12, R11, BP, BX, CX, R15) \ XORQ R15, R15 \ MOVQ 48+C, AX \ MOVQ 56+C, DX \ @@ -1587,7 +1669,7 @@ TEXT ·fp751Mul(SB), $96-24 MOVQ R13, 176+M0 \ MOVQ R14, 184+M0 \ \ // a[4-7] x p751p1_nz --> result: [reg_p2+48], [reg_p2+56], [reg_p2+64], and rbp, r8:r14 - MULS(32+M0, ·p751p1, 48+C, R8, R9, R13, R10, R14, R12, R11, BP, BX, CX, R15) \ + MULS(32+M0, ·P751p1, 48+C, R8, R9, R13, R10, R14, R12, R11, BP, BX, CX, R15) \ XORQ R15, R15 \ MOVQ 48+C, AX \ MOVQ 56+C, DX \ @@ -1626,7 +1708,7 @@ TEXT ·fp751Mul(SB), $96-24 MOVQ R13, 176+M0 \ MOVQ R14, 184+M0 \ \ // a[8-11] x p751p1_nz --> result: [reg_p2+48], [reg_p2+56], [reg_p2+64], and rbp, r8:r14 - MULS(64+M0, ·p751p1, 48+C, R8, R9, R13, R10, R14, R12, R11, BP, BX, CX, R15) \ + MULS(64+M0, ·P751p1, 48+C, R8, R9, R13, R10, R14, R12, R11, BP, BX, CX, R15) \ MOVQ 48+C, AX \ // Final result c1:c11 MOVQ 56+C, DX \ MOVQ 64+C, BX \ @@ -1653,7 +1735,7 @@ TEXT ·fp751Mul(SB), $96-24 MOVQ R13, 80+C \ MOVQ R14, 88+C -TEXT ·fp751MontgomeryReduce(SB), $0-16 +TEXT ·rdcP751(SB), $0-16 MOVQ z+0(FP), REG_P2 MOVQ x+8(FP), REG_P1 @@ -2279,54 +2361,7 @@ redc_with_mulx: REDC(0(REG_P2), 0(REG_P1), mul256x448bmi2) RET -TEXT ·fp751AddLazy(SB), NOSPLIT, $0-24 - - MOVQ z+0(FP), REG_P3 - MOVQ x+8(FP), REG_P1 - MOVQ y+16(FP), REG_P2 - - MOVQ (REG_P1), R8 - MOVQ (8)(REG_P1), R9 - MOVQ (16)(REG_P1), R10 - MOVQ (24)(REG_P1), R11 - MOVQ (32)(REG_P1), R12 - MOVQ (40)(REG_P1), R13 - MOVQ (48)(REG_P1), R14 - MOVQ (56)(REG_P1), R15 - MOVQ (64)(REG_P1), AX - MOVQ (72)(REG_P1), BX - MOVQ (80)(REG_P1), CX - MOVQ (88)(REG_P1), DI - - ADDQ (REG_P2), R8 - ADCQ (8)(REG_P2), R9 - ADCQ (16)(REG_P2), R10 - ADCQ (24)(REG_P2), R11 - ADCQ (32)(REG_P2), R12 - ADCQ (40)(REG_P2), R13 - ADCQ (48)(REG_P2), R14 - ADCQ (56)(REG_P2), R15 - ADCQ (64)(REG_P2), AX - ADCQ (72)(REG_P2), BX - ADCQ (80)(REG_P2), CX - ADCQ (88)(REG_P2), DI - - MOVQ R8, (REG_P3) - MOVQ R9, (8)(REG_P3) - MOVQ R10, (16)(REG_P3) - MOVQ R11, (24)(REG_P3) - MOVQ R12, (32)(REG_P3) - MOVQ R13, (40)(REG_P3) - MOVQ R14, (48)(REG_P3) - MOVQ R15, (56)(REG_P3) - MOVQ AX, (64)(REG_P3) - MOVQ BX, (72)(REG_P3) - MOVQ CX, (80)(REG_P3) - MOVQ DI, (88)(REG_P3) - - RET - -TEXT ·fp751X2AddLazy(SB), NOSPLIT, $0-24 +TEXT ·adlP751(SB), NOSPLIT, $0-24 MOVQ z+0(FP), REG_P3 MOVQ x+8(FP), REG_P1 @@ -2413,7 +2448,7 @@ TEXT ·fp751X2AddLazy(SB), NOSPLIT, $0-24 RET -TEXT ·fp751X2SubLazy(SB), NOSPLIT, $0-24 +TEXT ·sulP751(SB), NOSPLIT, $0-24 MOVQ z+0(FP), REG_P3 MOVQ x+8(FP), REG_P1 diff --git a/dh/sidh/internal/p751/arith_amd64_test.go b/dh/sidh/internal/p751/arith_amd64_test.go new file mode 100644 index 0000000..9aa58cf --- /dev/null +++ b/dh/sidh/internal/p751/arith_amd64_test.go @@ -0,0 +1,140 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +// +build amd64,!noasm + +package p751 + +import ( + "reflect" + "testing" + "testing/quick" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" + "golang.org/x/sys/cpu" +) + +type OptimFlag uint + +const ( + // Indicates that optimisation which uses MUL instruction should be used + kUse_MUL OptimFlag = 1 << 0 + // Indicates that optimisation which uses MULX instruction should be used + kUse_MULX = 1 << 1 + // Indicates that optimisation which uses MULX, ADOX and ADCX instructions should be used + kUse_MULXandADxX = 1 << 2 +) + +func resetCpuFeatures() { + HasBMI2 = cpu.X86.HasBMI2 + HasADXandBMI2 = cpu.X86.HasBMI2 && cpu.X86.HasADX +} + +// Utility function used for testing Mul implementations. Tests caller provided +// mulFunc against mul() +func testMul(t *testing.T, f1, f2 OptimFlag) { + doMulTest := func(multiplier, multiplicant common.Fp) bool { + defer resetCpuFeatures() + var resMulRef, resMulOptim common.FpX2 + + // Compute multiplier*multiplicant with first implementation + HasBMI2 = (kUse_MULX & f1) == kUse_MULX + HasADXandBMI2 = (kUse_MULXandADxX & f1) == kUse_MULXandADxX + mulP751(&resMulOptim, &multiplier, &multiplicant) + + // Compute multiplier*multiplicant with second implementation + HasBMI2 = (kUse_MULX & f2) == kUse_MULX + HasADXandBMI2 = (kUse_MULXandADxX & f2) == kUse_MULXandADxX + mulP751(&resMulRef, &multiplier, &multiplicant) + + // Compare results + return reflect.DeepEqual(resMulRef, resMulOptim) + } + + if err := quick.Check(doMulTest, quickCheckConfig); err != nil { + t.Error(err) + } +} + +// Utility function used for testing REDC implementations. Tests caller provided +// redcFunc against redc() +func testRedc(t *testing.T, f1, f2 OptimFlag) { + doRedcTest := func(aRR common.FpX2) bool { + defer resetCpuFeatures() + var resRedcF1, resRedcF2 common.Fp + var aRRcpy = aRR + + // Compute redc with first implementation + HasBMI2 = (kUse_MULX & f1) == kUse_MULX + HasADXandBMI2 = (kUse_MULXandADxX & f1) == kUse_MULXandADxX + rdcP751(&resRedcF1, &aRR) + + // Compute redc with second implementation + HasBMI2 = (kUse_MULX & f2) == kUse_MULX + HasADXandBMI2 = (kUse_MULXandADxX & f2) == kUse_MULXandADxX + rdcP751(&resRedcF2, &aRRcpy) + + // Compare results + return reflect.DeepEqual(resRedcF2, resRedcF1) + } + + if err := quick.Check(doRedcTest, quickCheckConfig); err != nil { + t.Error(err) + } +} + +// Ensures correctness of implementation of mul operation which uses MULX +func TestMulWithMULX(t *testing.T) { + defer resetCpuFeatures() + if !HasBMI2 { + t.Skip("MULX not supported by the platform") + } + testMul(t, kUse_MULX, kUse_MUL) +} + +// Ensures correctness of implementation of mul operation which uses MULX and ADOX/ADCX +func TestMulWithMULXADxX(t *testing.T) { + defer resetCpuFeatures() + if !HasADXandBMI2 { + t.Skip("MULX, ADCX and ADOX not supported by the platform") + } + testMul(t, kUse_MULXandADxX, kUse_MUL) +} + +// Ensures correctness of implementation of mul operation which uses MULX and ADOX/ADCX +func TestMulWithMULXADxXAgainstMULX(t *testing.T) { + defer resetCpuFeatures() + if !HasADXandBMI2 { + t.Skip("MULX, ADCX and ADOX not supported by the platform") + } + testMul(t, kUse_MULX, kUse_MULXandADxX) +} + +// Ensures correctness of Montgomery reduction implementation which uses MULX +func TestRedcWithMULX(t *testing.T) { + defer resetCpuFeatures() + if !HasBMI2 { + t.Skip("MULX not supported by the platform") + } + testRedc(t, kUse_MULX, kUse_MUL) +} + +// Ensures correctness of Montgomery reduction implementation which uses MULX +// and ADCX/ADOX. +func TestRedcWithMULXADxX(t *testing.T) { + defer resetCpuFeatures() + if !HasADXandBMI2 { + t.Skip("MULX, ADCX and ADOX not supported by the platform") + } + testRedc(t, kUse_MULXandADxX, kUse_MUL) +} + +// Ensures correctness of Montgomery reduction implementation which uses MULX +// and ADCX/ADOX. +func TestRedcWithMULXADxXAgainstMULX(t *testing.T) { + defer resetCpuFeatures() + if !HasADXandBMI2 { + t.Skip("MULX, ADCX and ADOX not supported by the platform") + } + testRedc(t, kUse_MULXandADxX, kUse_MULX) +} diff --git a/dh/sidh/p751/arith_arm64.s b/dh/sidh/internal/p751/arith_arm64.s similarity index 92% rename from dh/sidh/p751/arith_arm64.s rename to dh/sidh/internal/p751/arith_arm64.s index 730936e..2c564f9 100644 --- a/dh/sidh/p751/arith_arm64.s +++ b/dh/sidh/internal/p751/arith_arm64.s @@ -2,7 +2,7 @@ #include "textflag.h" -TEXT ·fp751ConditionalSwap(SB), NOSPLIT, $0-17 +TEXT ·cswapP751(SB), NOSPLIT, $0-17 MOVD x+0(FP), R0 MOVD y+8(FP), R1 MOVB choice+16(FP), R2 @@ -67,7 +67,7 @@ TEXT ·fp751ConditionalSwap(SB), NOSPLIT, $0-17 RET -TEXT ·fp751AddReduced(SB), NOSPLIT, $0-24 +TEXT ·addP751(SB), NOSPLIT, $0-24 MOVD z+0(FP), R2 MOVD x+8(FP), R0 MOVD y+16(FP), R1 @@ -102,20 +102,20 @@ TEXT ·fp751AddReduced(SB), NOSPLIT, $0-24 ADC R19, R14 // Subtract 2 * p751 in R15-R24 from the result in R3-R14 - LDP ·p751x2+0(SB), (R15, R16) + LDP ·P751x2+0(SB), (R15, R16) SUBS R15, R3 SBCS R16, R4 - LDP ·p751x2+40(SB), (R17, R19) + LDP ·P751x2+40(SB), (R17, R19) SBCS R16, R5 SBCS R16, R6 SBCS R16, R7 - LDP ·p751x2+56(SB), (R20, R21) + LDP ·P751x2+56(SB), (R20, R21) SBCS R17, R8 SBCS R19, R9 - LDP ·p751x2+72(SB), (R22, R23) + LDP ·P751x2+72(SB), (R22, R23) SBCS R20, R10 SBCS R21, R11 - MOVD ·p751x2+88(SB), R24 + MOVD ·P751x2+88(SB), R24 SBCS R22, R12 SBCS R23, R13 SBCS R24, R14 @@ -153,7 +153,7 @@ TEXT ·fp751AddReduced(SB), NOSPLIT, $0-24 RET -TEXT ·fp751SubReduced(SB), NOSPLIT, $0-24 +TEXT ·subP751(SB), NOSPLIT, $0-24 MOVD z+0(FP), R2 MOVD x+8(FP), R0 MOVD y+16(FP), R1 @@ -189,10 +189,10 @@ TEXT ·fp751SubReduced(SB), NOSPLIT, $0-24 SBC ZR, ZR, R15 // If x - y < 0, R15 is 1 and 2 * p751 should be added - LDP ·p751x2+0(SB), (R16, R17) + LDP ·P751x2+0(SB), (R16, R17) AND R15, R16 AND R15, R17 - LDP ·p751x2+40(SB), (R19, R20) + LDP ·P751x2+40(SB), (R19, R20) AND R15, R19 AND R15, R20 @@ -207,10 +207,10 @@ TEXT ·fp751SubReduced(SB), NOSPLIT, $0-24 STP (R7, R8), 32(R2) ADCS R20, R9 - LDP ·p751x2+56(SB), (R16, R17) + LDP ·P751x2+56(SB), (R16, R17) AND R15, R16 AND R15, R17 - LDP ·p751x2+72(SB), (R19, R20) + LDP ·P751x2+72(SB), (R19, R20) AND R15, R19 AND R15, R20 @@ -221,56 +221,14 @@ TEXT ·fp751SubReduced(SB), NOSPLIT, $0-24 STP (R11, R12), 64(R2) ADCS R20, R13 - MOVD ·p751x2+88(SB), R16 + MOVD ·P751x2+88(SB), R16 AND R15, R16 ADC R16, R14 STP (R13, R14), 80(R2) RET -TEXT ·fp751AddLazy(SB), NOSPLIT, $0-24 - MOVD z+0(FP), R2 - MOVD x+8(FP), R0 - MOVD y+16(FP), R1 - - // Load first summand into R3-R14 - // Add first summand and second summand and store result in R3-R14 - LDP 0(R0), (R3, R4) - LDP 0(R1), (R15, R16) - LDP 16(R0), (R5, R6) - LDP 16(R1), (R17, R19) - ADDS R15, R3 - ADCS R16, R4 - STP (R3, R4), 0(R2) - ADCS R17, R5 - ADCS R19, R6 - STP (R5, R6), 16(R2) - - LDP 32(R0), (R7, R8) - LDP 32(R1), (R15, R16) - LDP 48(R0), (R9, R10) - LDP 48(R1), (R17, R19) - ADCS R15, R7 - ADCS R16, R8 - STP (R7, R8), 32(R2) - ADCS R17, R9 - ADCS R19, R10 - STP (R9, R10), 48(R2) - - LDP 64(R0), (R11, R12) - LDP 64(R1), (R15, R16) - LDP 80(R0), (R13, R14) - LDP 80(R1), (R17, R19) - ADCS R15, R11 - ADCS R16, R12 - STP (R11, R12), 64(R2) - ADCS R17, R13 - ADC R19, R14 - STP (R13, R14), 80(R2) - - RET - -TEXT ·fp751X2AddLazy(SB), NOSPLIT, $0-24 +TEXT ·adlP751(SB), NOSPLIT, $0-24 MOVD z+0(FP), R2 MOVD x+8(FP), R0 MOVD y+16(FP), R1 @@ -343,7 +301,7 @@ TEXT ·fp751X2AddLazy(SB), NOSPLIT, $0-24 RET -TEXT ·fp751X2SubLazy(SB), NOSPLIT, $0-24 +TEXT ·sulP751(SB), NOSPLIT, $0-24 MOVD z+0(FP), R2 MOVD x+8(FP), R0 MOVD y+16(FP), R1 @@ -410,9 +368,9 @@ TEXT ·fp751X2SubLazy(SB), NOSPLIT, $0-24 SBC ZR, ZR, R15 // If x - y < 0, R15 is 1 and p751 should be added - MOVD ·p751+0(SB), R20 + MOVD ·P751+0(SB), R20 AND R15, R20 - LDP ·p751+40(SB), (R16, R17) + LDP ·P751+40(SB), (R16, R17) ADDS R20, R3 ADCS R20, R4 STP (R3, R4), 96(R2) @@ -421,21 +379,21 @@ TEXT ·fp751X2SubLazy(SB), NOSPLIT, $0-24 STP (R5, R6), 112(R2) ADCS R20, R7 - LDP ·p751+56(SB), (R19, R20) + LDP ·P751+56(SB), (R19, R20) AND R15, R16 AND R15, R17 ADCS R16, R8 STP (R7, R8), 128(R2) ADCS R17, R9 - LDP ·p751+72(SB), (R16, R17) + LDP ·P751+72(SB), (R16, R17) AND R15, R19 AND R15, R20 ADCS R19, R10 STP (R9, R10), 144(R2) ADCS R20, R11 - MOVD ·p751+88(SB), R19 + MOVD ·P751+88(SB), R19 AND R15, R16 AND R15, R17 ADCS R16, R12 @@ -607,7 +565,7 @@ TEXT ·fp751X2SubLazy(SB), NOSPLIT, $0-24 ADC ZR, Y2, T8 -TEXT ·fp751Mul(SB), NOSPLIT, $0-24 +TEXT ·mulP751(SB), NOSPLIT, $0-24 MOVD z+0(FP), R2 MOVD x+8(FP), R0 MOVD y+16(FP), R1 @@ -827,12 +785,12 @@ TEXT ·fp751Mul(SB), NOSPLIT, $0-24 RET -TEXT ·fp751MontgomeryReduce(SB), NOSPLIT, $0-16 +TEXT ·rdcP751(SB), NOSPLIT, $0-16 MOVD z+0(FP), R0 MOVD x+8(FP), R1 // Load p751+1 in R14-R17, R29, R19-R20, spread over arithmetic - LDP ·p751p1+40(SB), (R14, R15) + LDP ·P751p1+40(SB), (R14, R15) // z0-z11 will be R2-R13 // Load x0-x4 to z0-z4 and x5, spread over arithmetic LDP 0(R1), (R2, R3) @@ -852,7 +810,7 @@ TEXT ·fp751MontgomeryReduce(SB), NOSPLIT, $0-16 ADC R23, ZR, R26 MUL R3, R14, R22 - LDP ·p751p1+56(SB), (R16, R17) + LDP ·P751p1+56(SB), (R16, R17) UMULH R3, R14, R23 ADDS R22, R25 ADCS R23, R26 @@ -878,7 +836,7 @@ TEXT ·fp751MontgomeryReduce(SB), NOSPLIT, $0-16 ADC ZR, R25 MUL R4, R14, R22 - LDP ·p751p1+72(SB), (R29, R19) + LDP ·P751p1+72(SB), (R29, R19) UMULH R4, R14, R23 ADDS R22, R26 ADCS R23, R24 @@ -897,7 +855,7 @@ TEXT ·fp751MontgomeryReduce(SB), NOSPLIT, $0-16 ADC ZR, ZR, R26 MUL R3, R16, R22 - MOVD ·p751p1+88(SB), R20 + MOVD ·P751p1+88(SB), R20 UMULH R3, R16, R23 ADDS R22, R24 ADCS R23, R25 @@ -1454,33 +1412,33 @@ TEXT ·fp751MontgomeryReduce(SB), NOSPLIT, $0-16 RET -TEXT ·fp751StrongReduce(SB), NOSPLIT, $0-8 +TEXT ·modP751(SB), NOSPLIT, $0-8 MOVD x+0(FP), R0 // Keep x in R1-R12, p751 in R13-R21, subtract to R1-R12 - MOVD ·p751+0(SB), R13 + MOVD ·P751+0(SB), R13 LDP 0(R0), (R1, R2) LDP 16(R0), (R3, R4) SUBS R13, R1 SBCS R13, R2 LDP 32(R0), (R5, R6) - LDP ·p751+40(SB), (R14, R15) + LDP ·P751+40(SB), (R14, R15) SBCS R13, R3 SBCS R13, R4 LDP 48(R0), (R7, R8) - LDP ·p751+56(SB), (R16, R17) + LDP ·P751+56(SB), (R16, R17) SBCS R13, R5 SBCS R14, R6 LDP 64(R0), (R9, R10) - LDP ·p751+72(SB), (R19, R20) + LDP ·P751+72(SB), (R19, R20) SBCS R15, R7 SBCS R16, R8 LDP 80(R0), (R11, R12) - MOVD ·p751+88(SB), R21 + MOVD ·P751+88(SB), R21 SBCS R17, R9 SBCS R19, R10 diff --git a/dh/sidh/internal/p751/arith_decl.go b/dh/sidh/internal/p751/arith_decl.go new file mode 100644 index 0000000..8ff0bf4 --- /dev/null +++ b/dh/sidh/internal/p751/arith_decl.go @@ -0,0 +1,45 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +// +build amd64,!noasm arm64,!noasm + +package p751 + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// If choice = 0, leave x,y unchanged. If choice = 1, set x,y = y,x. +// If choice is neither 0 nor 1 then behaviour is undefined. +// This function executes in constant time. +//go:noescape +func cswapP751(x, y *Fp, choice uint8) + +// Compute z = x + y (mod p). +//go:noescape +func addP751(z, x, y *Fp) + +// Compute z = x - y (mod p). +//go:noescape +func subP751(z, x, y *Fp) + +// Compute z = x + y, without reducing mod p. +//go:noescape +func adlP751(z, x, y *FpX2) + +// Compute z = x - y, without reducing mod p. +//go:noescape +func sulP751(z, x, y *FpX2) + +// Reduce a field element in [0, 2*p) to one in [0,p). +//go:noescape +func modP751(x *Fp) + +// Computes z = x * y. +//go:noescape +func mulP751(z *FpX2, x, y *Fp) + +// Computes the Montgomery reduction z = x R^{-1} (mod 2*p). On return value +// of x may be changed. z=x not allowed. +//go:noescape +func rdcP751(z *Fp, x *FpX2) diff --git a/dh/sidh/internal/p751/arith_generic.go b/dh/sidh/internal/p751/arith_generic.go new file mode 100644 index 0000000..9fab653 --- /dev/null +++ b/dh/sidh/internal/p751/arith_generic.go @@ -0,0 +1,192 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +// +build noasm !amd64,!arm64 + +package p751 + +import ( + "math/bits" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Compute z = x + y (mod p). +func addP751(z, x, y *common.Fp) { + var carry uint64 + + // z=x+y % P751 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Add64(x[i], y[i], carry) + } + + // z = z - P751x2 + carry = 0 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Sub64(z[i], P751x2[i], carry) + } + + // if z<0 add P751x2 back + mask := uint64(0 - carry) + carry = 0 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Add64(z[i], P751x2[i]&mask, carry) + } +} + +// Compute z = x - y (mod p). +func subP751(z, x, y *common.Fp) { + var borrow uint64 + + for i := 0; i < FpWords; i++ { + z[i], borrow = bits.Sub64(x[i], y[i], borrow) + } + + mask := uint64(0 - borrow) + borrow = 0 + + for i := 0; i < FpWords; i++ { + z[i], borrow = bits.Add64(z[i], P751x2[i]&mask, borrow) + } +} + +// Conditionally swaps bits in x and y in constant time. +// mask indicates bits to be swapped (set bits are swapped) +// For details see "Hackers Delight, 2.20" +// +// Implementation doesn't actually depend on a prime field. +func cswapP751(x, y *common.Fp, mask uint8) { + var tmp, mask64 uint64 + + mask64 = 0 - uint64(mask) + for i := 0; i < FpWords; i++ { + tmp = mask64 & (x[i] ^ y[i]) + x[i] = tmp ^ x[i] + y[i] = tmp ^ y[i] + } +} + +// Perform Montgomery reduction: set z = x R^{-1} (mod 2*p) +// with R=2^(FpWords*64). Destroys the input value. +func rdcP751(z *common.Fp, x *common.FpX2) { + var carry, t, u, v uint64 + var hi, lo uint64 + var count int + + count = P751p1Zeros + + for i := 0; i < FpWords; i++ { + for j := 0; j < i; j++ { + if j < (i - count + 1) { + hi, lo = bits.Mul64(z[j], P751p1[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + } + v, carry = bits.Add64(v, x[i], 0) + u, carry = bits.Add64(u, 0, carry) + t += carry + + z[i] = v + v = u + u = t + t = 0 + } + + for i := FpWords; i < 2*FpWords-1; i++ { + if count > 0 { + count-- + } + for j := i - FpWords + 1; j < FpWords; j++ { + if j < (FpWords - count) { + hi, lo = bits.Mul64(z[j], P751p1[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + } + v, carry = bits.Add64(v, x[i], 0) + u, carry = bits.Add64(u, 0, carry) + + t += carry + z[i-FpWords] = v + v = u + u = t + t = 0 + } + v, _ = bits.Add64(v, x[2*FpWords-1], 0) + z[FpWords-1] = v +} + +// Compute z = x * y. +func mulP751(z *common.FpX2, x, y *common.Fp) { + var u, v, t uint64 + var hi, lo uint64 + var carry uint64 + + for i := uint64(0); i < FpWords; i++ { + for j := uint64(0); j <= i; j++ { + hi, lo = bits.Mul64(x[j], y[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + z[i] = v + v = u + u = t + t = 0 + } + + for i := FpWords; i < (2*FpWords)-1; i++ { + for j := i - FpWords + 1; j < FpWords; j++ { + hi, lo = bits.Mul64(x[j], y[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + z[i] = v + v = u + u = t + t = 0 + } + z[2*FpWords-1] = v +} + +// Compute z = x + y, without reducing mod p. +func adlP751(z, x, y *common.FpX2) { + var carry uint64 + for i := 0; i < 2*FpWords; i++ { + z[i], carry = bits.Add64(x[i], y[i], carry) + } +} + +// Reduce a field element in [0, 2*p) to one in [0,p). +func modP751(x *common.Fp) { + var borrow, mask uint64 + for i := 0; i < FpWords; i++ { + x[i], borrow = bits.Sub64(x[i], P751[i], borrow) + } + + // Sets all bits if borrow = 1 + mask = 0 - borrow + borrow = 0 + for i := 0; i < FpWords; i++ { + x[i], borrow = bits.Add64(x[i], P751[i]&mask, borrow) + } +} + +// Compute z = x - y, without reducing mod p. +func sulP751(z, x, y *common.FpX2) { + var borrow, mask uint64 + for i := 0; i < 2*FpWords; i++ { + z[i], borrow = bits.Sub64(x[i], y[i], borrow) + } + + // Sets all bits if borrow = 1 + mask = 0 - borrow + borrow = 0 + for i := FpWords; i < 2*FpWords; i++ { + z[i], borrow = bits.Add64(z[i], P751[i-FpWords]&mask, borrow) + } +} diff --git a/dh/sidh/internal/p751/arith_test.go b/dh/sidh/internal/p751/arith_test.go new file mode 100644 index 0000000..a8a544f --- /dev/null +++ b/dh/sidh/internal/p751/arith_test.go @@ -0,0 +1,101 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p751 + +import ( + "testing" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Package-level storage for this field element is intended to deter +// compiler optimizations. +var ( + benchmarkFp common.Fp + benchmarkFpX2 common.FpX2 + bench_x = common.Fp{17026702066521327207, 5108203422050077993, 10225396685796065916, 11153620995215874678, 6531160855165088358, 15302925148404145445, 1248821577836769963, 9789766903037985294, 7493111552032041328, 10838999828319306046, 18103257655515297935, 27403304611634} + bench_y = common.Fp{4227467157325093378, 10699492810770426363, 13500940151395637365, 12966403950118934952, 16517692605450415877, 13647111148905630666, 14223628886152717087, 7167843152346903316, 15855377759596736571, 4300673881383687338, 6635288001920617779, 30486099554235} + bench_z = common.FpX2{1595347748594595712, 10854920567160033970, 16877102267020034574, 12435724995376660096, 3757940912203224231, 8251999420280413600, 3648859773438820227, 17622716832674727914, 11029567000887241528, 11216190007549447055, 17606662790980286987, 4720707159513626555, 12887743598335030915, 14954645239176589309, 14178817688915225254, 1191346797768989683, 12629157932334713723, 6348851952904485603, 16444232588597434895, 7809979927681678066, 14642637672942531613, 3092657597757640067, 10160361564485285723, 240071237} +) + +func TestFpCswap(t *testing.T) { + var one = common.Fp{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + var two = common.Fp{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} + + var x = one + var y = two + + cswapP751(&x, &y, 0) + for i := 0; i < FpWords; i++ { + if (x[i] != one[i]) || (y[i] != two[i]) { + t.Error("Found", x, "expected", two) + } + } + + cswapP751(&x, &y, 1) + for i := 0; i < FpWords; i++ { + if (x[i] != two[i]) || (y[i] != one[i]) { + t.Error("Found", x, "expected", two) + } + } +} + +// Benchmarking for field arithmetic +func BenchmarkMul(b *testing.B) { + for n := 0; n < b.N; n++ { + mulP751(&benchmarkFpX2, &bench_x, &bench_y) + } +} + +func BenchmarkRdc(b *testing.B) { + z := bench_z + + // This benchmark actually computes garbage, because + // rdcP751 mangles its input, but since it's + // constant-time that shouldn't matter for the benchmarks. + for n := 0; n < b.N; n++ { + rdcP751(&benchmarkFp, &z) + } +} + +func BenchmarkAdd(b *testing.B) { + for n := 0; n < b.N; n++ { + addP751(&benchmarkFp, &bench_x, &bench_y) + } +} + +func BenchmarkSub(b *testing.B) { + for n := 0; n < b.N; n++ { + subP751(&benchmarkFp, &bench_x, &bench_y) + } +} + +func BenchmarkCswap(b *testing.B) { + x, y := bench_x, bench_y + for n := 0; n < b.N; n++ { + cswapP751(&x, &y, 1) + cswapP751(&x, &y, 0) + } +} + +func BenchmarkMod(b *testing.B) { + x := bench_x + for n := 0; n < b.N; n++ { + modP751(&x) + } +} + +func BenchmarkX2AddLazy(b *testing.B) { + x, y, z := bench_z, bench_z, bench_z + for n := 0; n < b.N; n++ { + adlP751(&x, &y, &z) + } +} + +func BenchmarkX2SubLazy(b *testing.B) { + x, y, z := bench_z, bench_z, bench_z + for n := 0; n < b.N; n++ { + sulP751(&x, &y, &z) + } +} diff --git a/dh/sidh/internal/p751/core.go b/dh/sidh/internal/p751/core.go new file mode 100644 index 0000000..fcc89f5 --- /dev/null +++ b/dh/sidh/internal/p751/core.go @@ -0,0 +1,282 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p751 + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// ----------------------------------------------------------------------------- +// Functions for traversing isogeny trees acoording to strategy. Key type 'A' is +// + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreePublicKeyA(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny4 + + cparam := CalcCurveParamsEquiv4(curve) + strat := params.A.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow2k(xR, &cparam, 2*k) + i += int(k) + } + cparam = phi.GenerateCurve(xR) + + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + *phiP = phi.EvaluatePoint(phiP) + *phiQ = phi.EvaluatePoint(phiQ) + *phiR = phi.EvaluatePoint(phiR) + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR needed +// for public key generation. +func traverseTreeSharedKeyA(curve *ProjectiveCurveParameters, xR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny4 + + cparam := CalcCurveParamsEquiv4(curve) + strat := params.A.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow2k(xR, &cparam, 2*k) + i += int(k) + } + cparam = phi.GenerateCurve(xR) + + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreePublicKeyB(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny3 + + cparam := CalcCurveParamsEquiv3(curve) + strat := params.B.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow3k(xR, &cparam, k) + i += int(k) + } + + cparam = phi.GenerateCurve(xR) + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + *phiP = phi.EvaluatePoint(phiP) + *phiQ = phi.EvaluatePoint(phiQ) + *phiR = phi.EvaluatePoint(phiR) + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreeSharedKeyB(curve *ProjectiveCurveParameters, xR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny3 + + cparam := CalcCurveParamsEquiv3(curve) + strat := params.B.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow3k(xR, &cparam, k) + i += int(k) + } + + cparam = phi.GenerateCurve(xR) + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Generate a public key in the 2-torsion group. Public key is a set +// of three x-coordinates: xP,xQ,x(P-Q), where P,Q are points on E_a(Fp2) +func PublicKeyGenA(pub3Pt *[3]Fp2, prvBytes []byte) { + var xPA, xQA, xRA ProjectivePoint + var xPB, xQB, xRB, xR ProjectivePoint + var invZP, invZQ, invZR Fp2 + var phi isogeny4 + + // Load points for A + xPA = ProjectivePoint{X: params.A.AffineP, Z: params.OneFp2} + xQA = ProjectivePoint{X: params.A.AffineQ, Z: params.OneFp2} + xRA = ProjectivePoint{X: params.A.AffineR, Z: params.OneFp2} + + // Load points for B + xRB = ProjectivePoint{X: params.B.AffineR, Z: params.OneFp2} + xQB = ProjectivePoint{X: params.B.AffineQ, Z: params.OneFp2} + xPB = ProjectivePoint{X: params.B.AffineP, Z: params.OneFp2} + + // Find isogeny kernel + xR = ScalarMul3Pt(¶ms.InitCurve, &xPA, &xQA, &xRA, params.A.SecretBitLen, prvBytes) + traverseTreePublicKeyA(¶ms.InitCurve, &xR, &xPB, &xQB, &xRB) + + // Secret isogeny + phi.GenerateCurve(&xR) + xPA = phi.EvaluatePoint(&xPB) + xQA = phi.EvaluatePoint(&xQB) + xRA = phi.EvaluatePoint(&xRB) + Fp2Batch3Inv(&xPA.Z, &xQA.Z, &xRA.Z, &invZP, &invZQ, &invZR) + + mul(&pub3Pt[0], &xPA.X, &invZP) + mul(&pub3Pt[1], &xQA.X, &invZQ) + mul(&pub3Pt[2], &xRA.X, &invZR) +} + +// Generate a public key in the 2-torsion group. Public key is a set +// of three x-coordinates: xP,xQ,x(P-Q), where P,Q are points on E_a(Fp2) +func PublicKeyGenB(pub3Pt *[3]Fp2, prvBytes []byte) { + var xPB, xQB, xRB, xR ProjectivePoint + var xPA, xQA, xRA ProjectivePoint + var invZP, invZQ, invZR Fp2 + var phi isogeny3 + + // Load points for B + xRB = ProjectivePoint{X: params.B.AffineR, Z: params.OneFp2} + xQB = ProjectivePoint{X: params.B.AffineQ, Z: params.OneFp2} + xPB = ProjectivePoint{X: params.B.AffineP, Z: params.OneFp2} + + // Load points for A + xPA = ProjectivePoint{X: params.A.AffineP, Z: params.OneFp2} + xQA = ProjectivePoint{X: params.A.AffineQ, Z: params.OneFp2} + xRA = ProjectivePoint{X: params.A.AffineR, Z: params.OneFp2} + + // Find isogeny kernel + xR = ScalarMul3Pt(¶ms.InitCurve, &xPB, &xQB, &xRB, params.B.SecretBitLen, prvBytes) + traverseTreePublicKeyB(¶ms.InitCurve, &xR, &xPA, &xQA, &xRA) + + phi.GenerateCurve(&xR) + xPB = phi.EvaluatePoint(&xPA) + xQB = phi.EvaluatePoint(&xQA) + xRB = phi.EvaluatePoint(&xRA) + Fp2Batch3Inv(&xPB.Z, &xQB.Z, &xRB.Z, &invZP, &invZQ, &invZR) + + mul(&pub3Pt[0], &xPB.X, &invZP) + mul(&pub3Pt[1], &xQB.X, &invZQ) + mul(&pub3Pt[2], &xRB.X, &invZR) +} + +// ----------------------------------------------------------------------------- +// Key agreement functions +// + +// Establishing shared keys in in 2-torsion group +func DeriveSecretA(ss, prv []byte, pub3Pt *[3]Fp2) { + var xP, xQ, xQmP ProjectivePoint + var xR ProjectivePoint + var phi isogeny4 + var jInv Fp2 + + // Recover curve coefficients + cparam := params.InitCurve + RecoverCoordinateA(&cparam, &pub3Pt[0], &pub3Pt[1], &pub3Pt[2]) + + // Find kernel of the morphism + xP = ProjectivePoint{X: pub3Pt[0], Z: params.OneFp2} + xQ = ProjectivePoint{X: pub3Pt[1], Z: params.OneFp2} + xQmP = ProjectivePoint{X: pub3Pt[2], Z: params.OneFp2} + xR = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, params.A.SecretBitLen, prv) + + // Traverse isogeny tree + traverseTreeSharedKeyA(&cparam, &xR) + + // Calculate j-invariant on isogeneus curve + c := phi.GenerateCurve(&xR) + RecoverCurveCoefficients4(&cparam, &c) + Jinvariant(&cparam, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(ss, &jInv, params.Bytelen) +} + +// Establishing shared keys in in 3-torsion group +func DeriveSecretB(ss, prv []byte, pub3Pt *[3]Fp2) { + var xP, xQ, xQmP ProjectivePoint + var xR ProjectivePoint + var phi isogeny3 + var jInv Fp2 + + // Recover curve coefficients + cparam := params.InitCurve + RecoverCoordinateA(&cparam, &pub3Pt[0], &pub3Pt[1], &pub3Pt[2]) + + // Find kernel of the morphism + xP = ProjectivePoint{X: pub3Pt[0], Z: params.OneFp2} + xQ = ProjectivePoint{X: pub3Pt[1], Z: params.OneFp2} + xQmP = ProjectivePoint{X: pub3Pt[2], Z: params.OneFp2} + xR = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, params.B.SecretBitLen, prv) + + // Traverse isogeny tree + traverseTreeSharedKeyB(&cparam, &xR) + + // Calculate j-invariant on isogeneus curve + c := phi.GenerateCurve(&xR) + RecoverCurveCoefficients3(&cparam, &c) + Jinvariant(&cparam, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(ss, &jInv, params.Bytelen) +} diff --git a/dh/sidh/internal/p751/curve.go b/dh/sidh/internal/p751/curve.go new file mode 100644 index 0000000..3a79ca2 --- /dev/null +++ b/dh/sidh/internal/p751/curve.go @@ -0,0 +1,362 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p751 + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Stores isogeny 3 curve constants +type isogeny3 struct { + K1 Fp2 + K2 Fp2 +} + +// Stores isogeny 4 curve constants +type isogeny4 struct { + isogeny3 + K3 Fp2 +} + +// Computes j-invariant for a curve y2=x3+A/Cx+x with A,C in F_(p^2). Result +// is returned in jBytes buffer, encoded in little-endian format. Caller +// provided jBytes buffer has to be big enough to j-invariant value. In case +// of SIDH, buffer size must be at least size of shared secret. +// Implementation corresponds to Algorithm 9 from SIKE. +func Jinvariant(cparams *ProjectiveCurveParameters, j *Fp2) { + var t0, t1 Fp2 + + sqr(j, &cparams.A) // j = A^2 + sqr(&t1, &cparams.C) // t1 = C^2 + add(&t0, &t1, &t1) // t0 = t1 + t1 + sub(&t0, j, &t0) // t0 = j - t0 + sub(&t0, &t0, &t1) // t0 = t0 - t1 + sub(j, &t0, &t1) // t0 = t0 - t1 + sqr(&t1, &t1) // t1 = t1^2 + mul(j, j, &t1) // j = j * t1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t0, &t0, &t0) // t0 = t0 + t0 + sqr(&t1, &t0) // t1 = t0^2 + mul(&t0, &t0, &t1) // t0 = t0 * t1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t0, &t0, &t0) // t0 = t0 + t0 + inv(j, j) // j = 1/j + mul(j, &t0, j) // j = t0 * j +} + +// Given affine points x(P), x(Q) and x(Q-P) in a extension field F_{p^2}, function +// recorvers projective coordinate A of a curve. This is Algorithm 10 from SIKE. +func RecoverCoordinateA(curve *ProjectiveCurveParameters, xp, xq, xr *Fp2) { + var t0, t1 Fp2 + + add(&t1, xp, xq) // t1 = Xp + Xq + mul(&t0, xp, xq) // t0 = Xp * Xq + mul(&curve.A, xr, &t1) // A = X(q-p) * t1 + add(&curve.A, &curve.A, &t0) // A = A + t0 + mul(&t0, &t0, xr) // t0 = t0 * X(q-p) + sub(&curve.A, &curve.A, ¶ms.OneFp2) // A = A - 1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t1, &t1, xr) // t1 = t1 + X(q-p) + add(&t0, &t0, &t0) // t0 = t0 + t0 + sqr(&curve.A, &curve.A) // A = A^2 + inv(&t0, &t0) // t0 = 1/t0 + mul(&curve.A, &curve.A, &t0) // A = A * t0 + sub(&curve.A, &curve.A, &t1) // A = A - t1 +} + +// Computes equivalence (A:C) ~ (A+2C : A-2C) +func CalcCurveParamsEquiv3(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv { + var coef CurveCoefficientsEquiv + var c2 Fp2 + + add(&c2, &cparams.C, &cparams.C) + // A24p = A+2*C + add(&coef.A, &cparams.A, &c2) + // A24m = A-2*C + sub(&coef.C, &cparams.A, &c2) + return coef +} + +// Computes equivalence (A:C) ~ (A+2C : 4C) +func CalcCurveParamsEquiv4(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv { + var coefEq CurveCoefficientsEquiv + + add(&coefEq.C, &cparams.C, &cparams.C) + // A24p = A+2C + add(&coefEq.A, &cparams.A, &coefEq.C) + // C24 = 4*C + add(&coefEq.C, &coefEq.C, &coefEq.C) + return coefEq +} + +// Helper function for RightToLeftLadder(). Returns A+2C / 4. +func CalcAplus2Over4(cparams *ProjectiveCurveParameters) (ret Fp2) { + var tmp Fp2 + + // 2C + add(&tmp, &cparams.C, &cparams.C) + // A+2C + add(&ret, &cparams.A, &tmp) + // 1/4C + add(&tmp, &tmp, &tmp) + inv(&tmp, &tmp) + // A+2C/4C + mul(&ret, &ret, &tmp) + return +} + +// Recovers (A:C) curve parameters from projectively equivalent (A+2C:A-2C). +func RecoverCurveCoefficients3(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) { + add(&cparams.A, &coefEq.A, &coefEq.C) + // cparams.A = 2*(A+2C+A-2C) = 4A + add(&cparams.A, &cparams.A, &cparams.A) + // cparams.C = (A+2C-A+2C) = 4C + sub(&cparams.C, &coefEq.A, &coefEq.C) + return +} + +// Recovers (A:C) curve parameters from projectively equivalent (A+2C:4C). +func RecoverCurveCoefficients4(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) { + // cparams.C = (4C)*1/2=2C + mul(&cparams.C, &coefEq.C, ¶ms.HalfFp2) + // cparams.A = A+2C - 2C = A + sub(&cparams.A, &coefEq.A, &cparams.C) + // cparams.C = 2C * 1/2 = C + mul(&cparams.C, &cparams.C, ¶ms.HalfFp2) +} + +// Combined coordinate doubling and differential addition. Takes projective points +// P,Q,Q-P and (A+2C)/4C curve E coefficient. Returns 2*P and P+Q calculated on E. +// Function is used only by RightToLeftLadder. Corresponds to Algorithm 5 of SIKE +func xDbladd(P, Q, QmP *ProjectivePoint, a24 *Fp2) (dblP, PaQ ProjectivePoint) { + var t0, t1, t2 Fp2 + + xQmP, zQmP := &QmP.X, &QmP.Z + xPaQ, zPaQ := &PaQ.X, &PaQ.Z + x2P, z2P := &dblP.X, &dblP.Z + xP, zP := &P.X, &P.Z + xQ, zQ := &Q.X, &Q.Z + + add(&t0, xP, zP) // t0 = Xp+Zp + sub(&t1, xP, zP) // t1 = Xp-Zp + sqr(x2P, &t0) // 2P.X = t0^2 + sub(&t2, xQ, zQ) // t2 = Xq-Zq + add(xPaQ, xQ, zQ) // Xp+q = Xq+Zq + mul(&t0, &t0, &t2) // t0 = t0 * t2 + mul(z2P, &t1, &t1) // 2P.Z = t1 * t1 + mul(&t1, &t1, xPaQ) // t1 = t1 * Xp+q + sub(&t2, x2P, z2P) // t2 = 2P.X - 2P.Z + mul(x2P, x2P, z2P) // 2P.X = 2P.X * 2P.Z + mul(xPaQ, a24, &t2) // Xp+q = A24 * t2 + sub(zPaQ, &t0, &t1) // Zp+q = t0 - t1 + add(z2P, xPaQ, z2P) // 2P.Z = Xp+q + 2P.Z + add(xPaQ, &t0, &t1) // Xp+q = t0 + t1 + mul(z2P, z2P, &t2) // 2P.Z = 2P.Z * t2 + sqr(zPaQ, zPaQ) // Zp+q = Zp+q ^ 2 + sqr(xPaQ, xPaQ) // Xp+q = Xp+q ^ 2 + mul(zPaQ, xQmP, zPaQ) // Zp+q = Xq-p * Zp+q + mul(xPaQ, zQmP, xPaQ) // Xp+q = Zq-p * Xp+q + return +} + +// Given the curve parameters, xP = x(P), computes xP = x([2^k]P) +// Safe to overlap xP, x2P. +func Pow2k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) { + var t0, t1 Fp2 + + x, z := &xP.X, &xP.Z + for i := uint32(0); i < k; i++ { + sub(&t0, x, z) // t0 = Xp - Zp + add(&t1, x, z) // t1 = Xp + Zp + sqr(&t0, &t0) // t0 = t0 ^ 2 + sqr(&t1, &t1) // t1 = t1 ^ 2 + mul(z, ¶ms.C, &t0) // Z2p = C24 * t0 + mul(x, z, &t1) // X2p = Z2p * t1 + sub(&t1, &t1, &t0) // t1 = t1 - t0 + mul(&t0, ¶ms.A, &t1) // t0 = A24+ * t1 + add(z, z, &t0) // Z2p = Z2p + t0 + mul(z, z, &t1) // Zp = Z2p * t1 + } +} + +// Given the curve parameters, xP = x(P), and k >= 0, compute xP = x([3^k]P). +// +// Safe to overlap xP, xR. +func Pow3k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) { + var t0, t1, t2, t3, t4, t5, t6 Fp2 + + x, z := &xP.X, &xP.Z + for i := uint32(0); i < k; i++ { + sub(&t0, x, z) // t0 = Xp - Zp + sqr(&t2, &t0) // t2 = t0^2 + add(&t1, x, z) // t1 = Xp + Zp + sqr(&t3, &t1) // t3 = t1^2 + add(&t4, &t1, &t0) // t4 = t1 + t0 + sub(&t0, &t1, &t0) // t0 = t1 - t0 + sqr(&t1, &t4) // t1 = t4^2 + sub(&t1, &t1, &t3) // t1 = t1 - t3 + sub(&t1, &t1, &t2) // t1 = t1 - t2 + mul(&t5, &t3, ¶ms.A) // t5 = t3 * A24+ + mul(&t3, &t3, &t5) // t3 = t5 * t3 + mul(&t6, &t2, ¶ms.C) // t6 = t2 * A24- + mul(&t2, &t2, &t6) // t2 = t2 * t6 + sub(&t3, &t2, &t3) // t3 = t2 - t3 + sub(&t2, &t5, &t6) // t2 = t5 - t6 + mul(&t1, &t2, &t1) // t1 = t2 * t1 + add(&t2, &t3, &t1) // t2 = t3 + t1 + sqr(&t2, &t2) // t2 = t2^2 + mul(x, &t2, &t4) // X3p = t2 * t4 + sub(&t1, &t3, &t1) // t1 = t3 - t1 + sqr(&t1, &t1) // t1 = t1^2 + mul(z, &t1, &t0) // Z3p = t1 * t0 + } +} + +// Set (y1, y2, y3) = (1/x1, 1/x2, 1/x3). +// +// All xi, yi must be distinct. +func Fp2Batch3Inv(x1, x2, x3, y1, y2, y3 *Fp2) { + var x1x2, t Fp2 + + mul(&x1x2, x1, x2) // x1*x2 + mul(&t, &x1x2, x3) // 1/(x1*x2*x3) + inv(&t, &t) + mul(y1, &t, x2) // 1/x1 + mul(y1, y1, x3) + mul(y2, &t, x1) // 1/x2 + mul(y2, y2, x3) + mul(y3, &t, &x1x2) // 1/x3 +} + +// Scalarmul3Pt is a right-to-left point multiplication that given the +// x-coordinate of P, Q and P-Q calculates the x-coordinate of R=Q+[scalar]P. +// nbits must be smaller or equal to len(scalar). +func ScalarMul3Pt(cparams *ProjectiveCurveParameters, P, Q, PmQ *ProjectivePoint, nbits uint, scalar []uint8) ProjectivePoint { + var R0, R2, R1 ProjectivePoint + aPlus2Over4 := CalcAplus2Over4(cparams) + R1 = *P + R2 = *PmQ + R0 = *Q + + // Iterate over the bits of the scalar, bottom to top + prevBit := uint8(0) + for i := uint(0); i < nbits; i++ { + bit := (scalar[i>>3] >> (i & 7) & 1) + swap := prevBit ^ bit + prevBit = bit + cswap(&R1.X, &R1.Z, &R2.X, &R2.Z, swap) + R0, R2 = xDbladd(&R0, &R2, &R1, &aPlus2Over4) + } + cswap(&R1.X, &R1.Z, &R2.X, &R2.Z, prevBit) + return R1 +} + +// Given a three-torsion point p = x(PB) on the curve E_(A:C), construct the +// three-isogeny phi : E_(A:C) -> E_(A:C)/ = E_(A':C'). +// +// Input: (XP_3: ZP_3), where P_3 has exact order 3 on E_A/C +// Output: * Curve coordinates (A' + 2C', A' - 2C') corresponding to E_A'/C' = A_E/C/ +// * Isogeny phi with constants in F_p^2 +func (phi *isogeny3) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv { + var t0, t1, t2, t3, t4 Fp2 + var coefEq CurveCoefficientsEquiv + var K1, K2 = &phi.K1, &phi.K2 + + sub(K1, &p.X, &p.Z) // K1 = XP3 - ZP3 + sqr(&t0, K1) // t0 = K1^2 + add(K2, &p.X, &p.Z) // K2 = XP3 + ZP3 + sqr(&t1, K2) // t1 = K2^2 + add(&t2, &t0, &t1) // t2 = t0 + t1 + add(&t3, K1, K2) // t3 = K1 + K2 + sqr(&t3, &t3) // t3 = t3^2 + sub(&t3, &t3, &t2) // t3 = t3 - t2 + add(&t2, &t1, &t3) // t2 = t1 + t3 + add(&t3, &t3, &t0) // t3 = t3 + t0 + add(&t4, &t3, &t0) // t4 = t3 + t0 + add(&t4, &t4, &t4) // t4 = t4 + t4 + add(&t4, &t1, &t4) // t4 = t1 + t4 + mul(&coefEq.C, &t2, &t4) // A24m = t2 * t4 + add(&t4, &t1, &t2) // t4 = t1 + t2 + add(&t4, &t4, &t4) // t4 = t4 + t4 + add(&t4, &t0, &t4) // t4 = t0 + t4 + mul(&t4, &t3, &t4) // t4 = t3 * t4 + sub(&t0, &t4, &coefEq.C) // t0 = t4 - A24m + add(&coefEq.A, &coefEq.C, &t0) // A24p = A24m + t0 + return coefEq +} + +// Given a 3-isogeny phi and a point pB = x(PB), compute x(QB), the x-coordinate +// of the image QB = phi(PB) of PB under phi : E_(A:C) -> E_(A':C'). +// +// The output xQ = x(Q) is then a point on the curve E_(A':C'); the curve +// parameters are returned by the GenerateCurve function used to construct phi. +func (phi *isogeny3) EvaluatePoint(p *ProjectivePoint) ProjectivePoint { + var t0, t1, t2 Fp2 + var q ProjectivePoint + var K1, K2 = &phi.K1, &phi.K2 + var px, pz = &p.X, &p.Z + + add(&t0, px, pz) // t0 = XQ + ZQ + sub(&t1, px, pz) // t1 = XQ - ZQ + mul(&t0, K1, &t0) // t2 = K1 * t0 + mul(&t1, K2, &t1) // t1 = K2 * t1 + add(&t2, &t0, &t1) // t2 = t0 + t1 + sub(&t0, &t1, &t0) // t0 = t1 - t0 + sqr(&t2, &t2) // t2 = t2 ^ 2 + sqr(&t0, &t0) // t0 = t0 ^ 2 + mul(&q.X, px, &t2) // XQ'= XQ * t2 + mul(&q.Z, pz, &t0) // ZQ'= ZQ * t0 + return q +} + +// Given a four-torsion point p = x(PB) on the curve E_(A:C), construct the +// four-isogeny phi : E_(A:C) -> E_(A:C)/ = E_(A':C'). +// +// Input: (XP_4: ZP_4), where P_4 has exact order 4 on E_A/C +// Output: * Curve coordinates (A' + 2C', 4C') corresponding to E_A'/C' = A_E/C/ +// * Isogeny phi with constants in F_p^2 +func (phi *isogeny4) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv { + var coefEq CurveCoefficientsEquiv + var xp4, zp4 = &p.X, &p.Z + var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3 + + sub(K2, xp4, zp4) + add(K3, xp4, zp4) + sqr(K1, zp4) + add(K1, K1, K1) + sqr(&coefEq.C, K1) + add(K1, K1, K1) + sqr(&coefEq.A, xp4) + add(&coefEq.A, &coefEq.A, &coefEq.A) + sqr(&coefEq.A, &coefEq.A) + return coefEq +} + +// Given a 4-isogeny phi and a point xP = x(P), compute x(Q), the x-coordinate +// of the image Q = phi(P) of P under phi : E_(A:C) -> E_(A':C'). +// +// Input: Isogeny returned by GenerateCurve and point q=(Qx,Qz) from E0_A/C +// Output: Corresponding point q from E1_A'/C', where E1 is 4-isogenous to E0 +func (phi *isogeny4) EvaluatePoint(p *ProjectivePoint) ProjectivePoint { + var t0, t1 Fp2 + var q = *p + var xq, zq = &q.X, &q.Z + var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3 + + add(&t0, xq, zq) + sub(&t1, xq, zq) + mul(xq, &t0, K2) + mul(zq, &t1, K3) + mul(&t0, &t0, &t1) + mul(&t0, &t0, K1) + add(&t1, xq, zq) + sub(zq, xq, zq) + sqr(&t1, &t1) + sqr(zq, zq) + add(xq, &t0, &t1) + sub(&t0, zq, &t0) + mul(xq, xq, &t1) + mul(zq, zq, &t0) + return q +} diff --git a/dh/sidh/internal/p751/curve_test.go b/dh/sidh/internal/p751/curve_test.go new file mode 100644 index 0000000..c34ce56 --- /dev/null +++ b/dh/sidh/internal/p751/curve_test.go @@ -0,0 +1,100 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p751 + +import ( + "bytes" + "testing" + + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +func vartimeEqProjFp2(lhs, rhs *ProjectivePoint) bool { + var t0, t1 Fp2 + mul(&t0, &lhs.X, &rhs.Z) + mul(&t1, &lhs.Z, &rhs.X) + return vartimeEqFp2(&t0, &t1) +} + +func toAffine(point *ProjectivePoint) *Fp2 { + var affineX Fp2 + inv(&affineX, &point.Z) + mul(&affineX, &affineX, &point.X) + return &affineX +} + +func Test_jInvariant(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var jbufRes = make([]byte, params.SharedSecretSize) + var jbufExp = make([]byte, params.SharedSecretSize) + var jInv Fp2 + + Jinvariant(&curve, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(jbufRes, &jInv, params.Bytelen) + + jInv = expectedJ + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(jbufExp, &jInv, params.Bytelen) + + if !bytes.Equal(jbufRes[:], jbufExp[:]) { + t.Error("Computed incorrect j-invariant: found\n", jbufRes, "\nexpected\n", jbufExp) + } +} + +func TestProjectivePointVartimeEq(t *testing.T) { + var xP ProjectivePoint + + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + xQ := xP + + // Scale xQ, which results in the same projective point + mul(&xQ.X, &xQ.X, &curveA) + mul(&xQ.Z, &xQ.Z, &curveA) + if !vartimeEqProjFp2(&xP, &xQ) { + t.Error("Expected the scaled point to be equal to the original") + } +} + +func TestPointMulVersusSage(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var cparams = CalcCurveParamsEquiv4(&curve) + var xP ProjectivePoint + + // x 2 + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow2k(&xP, &cparams, 1) + afxQ := toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP2) { + t.Error("\nExpected\n", affineXP2, "\nfound\n", afxQ) + } + + // x 4 + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow2k(&xP, &cparams, 2) + afxQ = toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP4) { + t.Error("\nExpected\n", affineXP4, "\nfound\n", afxQ) + } +} + +func TestPointMul9VersusSage(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var cparams = CalcCurveParamsEquiv3(&curve) + var xP ProjectivePoint + + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow3k(&xP, &cparams, 2) + afxQ := toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP9) { + t.Error("\nExpected\n", affineXP9, "\nfound\n", afxQ) + } +} + +func BenchmarkThreePointLadder(b *testing.B) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + for n := 0; n < b.N; n++ { + ScalarMul3Pt(&curve, &threePointLadderInputs[0], &threePointLadderInputs[1], &threePointLadderInputs[2], uint(len(scalar3Pt)*8), scalar3Pt[:]) + } +} diff --git a/dh/sidh/internal/p751/doc.go b/dh/sidh/internal/p751/doc.go new file mode 100644 index 0000000..fb774fe --- /dev/null +++ b/dh/sidh/internal/p751/doc.go @@ -0,0 +1,2 @@ +// Package p751 provides implementation of field arithmetic used in SIDH and SIKE. +package p751 diff --git a/dh/sidh/internal/p751/fp2.go b/dh/sidh/internal/p751/fp2.go new file mode 100644 index 0000000..ed41019 --- /dev/null +++ b/dh/sidh/internal/p751/fp2.go @@ -0,0 +1,195 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p751 + +import ( + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Montgomery multiplication. Input values must be already +// in Montgomery domain. +func mulP(dest, lhs, rhs *common.Fp) { + var ab common.FpX2 + mulP751(&ab, lhs, rhs) // = a*b*R*R + rdcP751(dest, &ab) // = a*b*R mod p +} + +// Set dest = x^((p-3)/4). If x is square, this is 1/sqrt(x). +// Uses variation of sliding-window algorithm from with window size +// of 5 and least to most significant bit sliding (left-to-right) +// See HAC 14.85 for general description. +// +// Allowed to overlap x with dest. +// All values in Montgomery domains +// Set dest = x^(2^k), for k >= 1, by repeated squarings. +func p34(dest, x *common.Fp) { + var lookup [16]common.Fp + + // This performs sum(powStrategy) + 1 squarings and len(lookup) + len(mulStrategy) + // multiplications. + powStrategy := []uint8{5, 7, 6, 2, 10, 4, 6, 9, 8, 5, 9, 4, 7, 5, 5, 4, 8, 3, 9, 5, 5, 4, 10, 4, 6, 6, 6, 5, 8, 9, 3, 4, 9, 4, 5, 6, 6, 2, 9, 4, 5, 5, 5, 7, 7, 9, 4, 6, 4, 8, 5, 8, 6, 6, 2, 9, 7, 4, 8, 8, 8, 4, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2} + mulStrategy := []uint8{15, 11, 10, 0, 15, 3, 3, 3, 4, 4, 9, 7, 11, 11, 5, 3, 12, 2, 10, 8, 5, 2, 8, 3, 5, 4, 11, 4, 0, 9, 2, 1, 12, 7, 5, 14, 15, 0, 14, 5, 6, 4, 5, 13, 6, 9, 7, 15, 1, 14, 11, 15, 12, 5, 0, 10, 9, 7, 7, 10, 14, 6, 11, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1} + initialMul := uint8(13) + + // Precompute lookup table of odd multiples of x for window + // size k=5. + var xx common.Fp + mulP(&xx, x, x) + lookup[0] = *x + for i := 1; i < 16; i++ { + mulP(&lookup[i], &lookup[i-1], &xx) + } + + // Now lookup = {x, x^3, x^5, ... } + // so that lookup[i] = x^{2*i + 1} + // so that lookup[k/2] = x^k, for odd k + *dest = lookup[initialMul] + for i := uint8(0); i < uint8(len(powStrategy)); i++ { + mulP(dest, dest, dest) + for j := uint8(1); j < powStrategy[i]; j++ { + mulP(dest, dest, dest) + } + mulP(dest, dest, &lookup[mulStrategy[i]]) + } +} + +func add(dest, lhs, rhs *common.Fp2) { + addP751(&dest.A, &lhs.A, &rhs.A) + addP751(&dest.B, &lhs.B, &rhs.B) +} + +func sub(dest, lhs, rhs *common.Fp2) { + subP751(&dest.A, &lhs.A, &rhs.A) + subP751(&dest.B, &lhs.B, &rhs.B) +} + +func mul(dest, lhs, rhs *common.Fp2) { + var bMinA, cMinD common.Fp + var ac, bd common.FpX2 + var adPlusBc common.FpX2 + var acMinBd common.FpX2 + + // Let (a,b,c,d) = (lhs.a,lhs.b,rhs.a,rhs.b). + // + // (a + bi)*(c + di) = (a*c - b*d) + (a*d + b*c)i + // + // Use Karatsuba's trick: note that + // + // (b - a)*(c - d) = (b*c + a*d) - a*c - b*d + // + // so (a*d + b*c) = (b-a)*(c-d) + a*c + b*d. + mulP751(&ac, &lhs.A, &rhs.A) // = a*c*R*R + mulP751(&bd, &lhs.B, &rhs.B) // = b*d*R*R + subP751(&bMinA, &lhs.B, &lhs.A) // = (b-a)*R + subP751(&cMinD, &rhs.A, &rhs.B) // = (c-d)*R + mulP751(&adPlusBc, &bMinA, &cMinD) // = (b-a)*(c-d)*R*R + adlP751(&adPlusBc, &adPlusBc, &ac) // = ((b-a)*(c-d) + a*c)*R*R + adlP751(&adPlusBc, &adPlusBc, &bd) // = ((b-a)*(c-d) + a*c + b*d)*R*R + rdcP751(&dest.B, &adPlusBc) // = (a*d + b*c)*R mod p + sulP751(&acMinBd, &ac, &bd) // = (a*c - b*d)*R*R + rdcP751(&dest.A, &acMinBd) // = (a*c - b*d)*R mod p +} + +// Set dest = 1/x +// +// Allowed to overlap dest with x. +// +// Returns dest to allow chaining operations. +func inv(dest, x *common.Fp2) { + var e1, e2 common.FpX2 + var f1, f2 common.Fp + + // We want to compute + // + // 1 1 (a - bi) (a - bi) + // -------- = -------- -------- = ----------- + // (a + bi) (a + bi) (a - bi) (a^2 + b^2) + // + // Letting c = 1/(a^2 + b^2), this is + // + // 1/(a+bi) = a*c - b*ci. + + mulP751(&e1, &x.A, &x.A) // = a*a*R*R + mulP751(&e2, &x.B, &x.B) // = b*b*R*R + adlP751(&e1, &e1, &e2) // = (a^2 + b^2)*R*R + rdcP751(&f1, &e1) // = (a^2 + b^2)*R mod p + // Now f1 = a^2 + b^2 + + mulP(&f2, &f1, &f1) + p34(&f2, &f2) + mulP(&f2, &f2, &f2) + mulP(&f2, &f2, &f1) + + mulP751(&e1, &x.A, &f2) + rdcP751(&dest.A, &e1) + + subP751(&f1, &common.Fp{}, &x.B) + mulP751(&e1, &f1, &f2) + rdcP751(&dest.B, &e1) +} + +func sqr(dest, x *common.Fp2) { + var a2, aPlusB, aMinusB common.Fp + var a2MinB2, ab2 common.FpX2 + + a := &x.A + b := &x.B + + // (a + bi)*(a + bi) = (a^2 - b^2) + 2abi. + addP751(&a2, a, a) // = a*R + a*R = 2*a*R + addP751(&aPlusB, a, b) // = a*R + b*R = (a+b)*R + subP751(&aMinusB, a, b) // = a*R - b*R = (a-b)*R + mulP751(&a2MinB2, &aPlusB, &aMinusB) // = (a+b)*(a-b)*R*R = (a^2 - b^2)*R*R + mulP751(&ab2, &a2, b) // = 2*a*b*R*R + rdcP751(&dest.A, &a2MinB2) // = (a^2 - b^2)*R mod p + rdcP751(&dest.B, &ab2) // = 2*a*b*R mod p +} + +// In case choice == 1, performs following swap in constant time: +// xPx <-> xQx +// xPz <-> xQz +// Otherwise returns xPx, xPz, xQx, xQz unchanged +func cswap(xPx, xPz, xQx, xQz *common.Fp2, choice uint8) { + cswapP751(&xPx.A, &xQx.A, choice) + cswapP751(&xPx.B, &xQx.B, choice) + cswapP751(&xPz.A, &xQz.A, choice) + cswapP751(&xPz.B, &xQz.B, choice) +} + +// Converts in.A and in.B to Montgomery domain and stores +// in 'out' +// out.A = in.A * R mod p +// out.B = in.B * R mod p +// Performs v = v*R^2*R^(-1) mod p, for both in.A and in.B +func ToMontgomery(out, in *common.Fp2) { + var aRR common.FpX2 + + // a*R*R + mulP751(&aRR, &in.A, &P751R2) + // a*R mod p + rdcP751(&out.A, &aRR) + mulP751(&aRR, &in.B, &P751R2) + rdcP751(&out.B, &aRR) +} + +// Converts in.A and in.B from Montgomery domain and stores +// in 'out' +// out.A = in.A mod p +// out.B = in.B mod p +// +// After returning from the call 'in' is not modified. +func FromMontgomery(out, in *common.Fp2) { + var aR common.FpX2 + + // convert from montgomery domain + copy(aR[:], in.A[:]) + rdcP751(&out.A, &aR) // = a mod p in [0, 2p) + modP751(&out.A) // = a mod p in [0, p) + for i := range aR { + aR[i] = 0 + } + copy(aR[:], in.B[:]) + rdcP751(&out.B, &aR) + modP751(&out.B) +} diff --git a/dh/sidh/internal/p751/fp2_test.go b/dh/sidh/internal/p751/fp2_test.go new file mode 100644 index 0000000..b276d12 --- /dev/null +++ b/dh/sidh/internal/p751/fp2_test.go @@ -0,0 +1,245 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package p751 + +import ( + "math/rand" + "reflect" + "testing" + "testing/quick" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +type testParams struct { + Point common.ProjectivePoint + Cparam common.ProjectiveCurveParameters + ExtElem common.Fp2 +} + +// Returns true if lhs = rhs. Takes variable time. +func vartimeEqFp2(lhs, rhs *common.Fp2) bool { + a := *lhs + b := *rhs + + modP751(&a.A) + modP751(&a.B) + modP751(&b.A) + modP751(&b.B) + + eq := true + for i := 0; i < FpWords && eq; i++ { + eq = eq && (a.A[i] == b.A[i]) + eq = eq && (a.B[i] == b.B[i]) + } + return eq +} + +func (testParams) generateFp2(rand *rand.Rand) common.Fp2 { + // Generation strategy: low limbs taken from [0,2^64); high limb + // taken from smaller range + // + // Size hint is ignored since all elements are fixed size. + // + // Field elements taken in range [0,2p). Emulate this by capping + // the high limb by the top digit of 2*p-1: + // + // sage: (2*p-1).digits(2^64)[-1] + // + // This still allows generating values >= 2p, but hopefully that + // excess is OK (and if it's not, we'll find out, because it's for + // testing...) + highLimb := rand.Uint64() % P751x2[FpWords-1] + fpElementGen := func() (fp common.Fp) { + for i := 0; i < (FpWords - 1); i++ { + fp[i] = rand.Uint64() + } + fp[FpWords-1] = highLimb + return fp + } + return common.Fp2{A: fpElementGen(), B: fpElementGen()} +} + +func (c testParams) Generate(rand *rand.Rand, size int) reflect.Value { + return reflect.ValueOf( + testParams{ + common.ProjectivePoint{ + X: c.generateFp2(rand), + Z: c.generateFp2(rand), + }, + common.ProjectiveCurveParameters{ + A: c.generateFp2(rand), + C: c.generateFp2(rand), + }, + c.generateFp2(rand), + }) +} + +func TestOne(t *testing.T) { + var tmp common.Fp2 + + mul(&tmp, ¶ms.OneFp2, ¶ms.A.AffineP) + if !vartimeEqFp2(&tmp, ¶ms.A.AffineP) { + t.Error("Not equal 1") + } +} + +func TestFp2ToBytesRoundTrip(t *testing.T) { + roundTrips := func(x testParams) bool { + var xBytes = make([]byte, 2*params.Bytelen) + var xPrime common.Fp2 + + common.Fp2ToBytes(xBytes[:], &x.ExtElem, params.Bytelen) + common.BytesToFp2(&xPrime, xBytes[:], params.Bytelen) + return vartimeEqFp2(&xPrime, &x.ExtElem) + } + + if err := quick.Check(roundTrips, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2MulDistributesOverAdd(t *testing.T) { + mulDistributesOverAdd := func(x, y, z testParams) bool { + // Compute t1 = (x+y)*z + t1 := new(common.Fp2) + add(t1, &x.ExtElem, &y.ExtElem) + mul(t1, t1, &z.ExtElem) + + // Compute t2 = x*z + y*z + t2 := new(common.Fp2) + t3 := new(common.Fp2) + mul(t2, &x.ExtElem, &z.ExtElem) + mul(t3, &y.ExtElem, &z.ExtElem) + add(t2, t2, t3) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(mulDistributesOverAdd, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2MulIsAssociative(t *testing.T) { + isAssociative := func(x, y, z testParams) bool { + // Compute t1 = (x*y)*z + t1 := new(common.Fp2) + mul(t1, &x.ExtElem, &y.ExtElem) + mul(t1, t1, &z.ExtElem) + + // Compute t2 = (y*z)*x + t2 := new(common.Fp2) + mul(t2, &y.ExtElem, &z.ExtElem) + mul(t2, t2, &x.ExtElem) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(isAssociative, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2SquareMatchesMul(t *testing.T) { + sqrMatchesMul := func(x testParams) bool { + // Compute t1 = (x*x) + t1 := new(common.Fp2) + mul(t1, &x.ExtElem, &x.ExtElem) + + // Compute t2 = x^2 + t2 := new(common.Fp2) + sqr(t2, &x.ExtElem) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(sqrMatchesMul, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2Inv(t *testing.T) { + inverseIsCorrect := func(x testParams) bool { + z := new(common.Fp2) + inv(z, &x.ExtElem) + + // Now z = (1/x), so (z * x) * x == x + mul(z, z, &x.ExtElem) + mul(z, z, &x.ExtElem) + + return vartimeEqFp2(z, &x.ExtElem) + } + + // This is more expensive; run fewer tests + var quickCheckConfig = &quick.Config{MaxCount: (1 << 11)} + if err := quick.Check(inverseIsCorrect, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2Batch3Inv(t *testing.T) { + batchInverseIsCorrect := func(x1, x2, x3 testParams) bool { + var x1Inv, x2Inv, x3Inv common.Fp2 + inv(&x1Inv, &x1.ExtElem) + inv(&x2Inv, &x2.ExtElem) + inv(&x3Inv, &x3.ExtElem) + + var y1, y2, y3 common.Fp2 + Fp2Batch3Inv(&x1.ExtElem, &x2.ExtElem, &x3.ExtElem, &y1, &y2, &y3) + + return (vartimeEqFp2(&x1Inv, &y1) && vartimeEqFp2(&x2Inv, &y2) && vartimeEqFp2(&x3Inv, &y3)) + } + + // This is more expensive; run fewer tests + var quickCheckConfig = &quick.Config{MaxCount: (1 << 8)} + if err := quick.Check(batchInverseIsCorrect, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func BenchmarkFp2Mul(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + mul(w, z, z) + } +} + +func BenchmarkFp2Inv(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + inv(w, z) + } +} + +func BenchmarkFp2Square(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + sqr(w, z) + } +} + +func BenchmarkFp2Add(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + add(w, z, z) + } +} + +func BenchmarkFp2Sub(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + sub(w, z, z) + } +} diff --git a/dh/sidh/internal/p751/params.go b/dh/sidh/internal/p751/params.go new file mode 100644 index 0000000..d6f5a40 --- /dev/null +++ b/dh/sidh/internal/p751/params.go @@ -0,0 +1,249 @@ +package p751 + +//go:generate go run ../templates/gen.go P751 + +import ( + "github.com/henrydcase/nobs/dh/sidh/internal/common" + "golang.org/x/sys/cpu" +) + +const ( + // Number of uint64 limbs used to store field element + FpWords = 12 +) + +var ( + // HasBMI2 signals support for MULX which is in BMI2 + HasBMI2 = cpu.X86.HasBMI2 + // HasADXandBMI2 signals support for ADX and BMI2 + HasADXandBMI2 = cpu.X86.HasBMI2 && cpu.X86.HasADX + // P751 is a prime used by field Fp751 + P751 = common.Fp{ + 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, + 0xffffffffffffffff, 0xffffffffffffffff, 0xeeafffffffffffff, + 0xe3ec968549f878a8, 0xda959b1a13f7cc76, 0x084e9867d6ebe876, + 0x8562b5045cb25748, 0x0e12909f97badc66, 0x00006fe5d541f71c} + + // P751x2 = 2*p751 - 1 + P751x2 = common.Fp{ + 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xDD5FFFFFFFFFFFFF, + 0xC7D92D0A93F0F151, 0xB52B363427EF98ED, 0x109D30CFADD7D0ED, + 0x0AC56A08B964AE90, 0x1C25213F2F75B8CD, 0x0000DFCBAA83EE38} + + // P751p1 = p751 + 1 + P751p1 = common.Fp{ + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0xeeb0000000000000, + 0xe3ec968549f878a8, 0xda959b1a13f7cc76, 0x084e9867d6ebe876, + 0x8562b5045cb25748, 0x0e12909f97badc66, 0x00006fe5d541f71c} + + // P751R2 = (2^768)^2 mod p + P751R2 = common.Fp{ + 0x233046449DAD4058, 0xDB010161A696452A, 0x5E36941472E3FD8E, + 0xF40BFE2082A2E706, 0x4932CCA8904F8751, 0x1F735F1F1EE7FC81, + 0xA24F4D80C1048E18, 0xB56C383CCDB607C5, 0x441DD47B735F9C90, + 0x5673ED2C6A6AC82A, 0x06C905261132294B, 0x000041AD830F1F35} + + // P751p1Zeros number of 0 digits in the least significant part of P751+1 + P751p1Zeros = 5 + + // 1*R mod p + one = common.Fp2{ + A: common.Fp{ + 0x00000000000249ad, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x8310000000000000, + 0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, + 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x00002d5b24bce5e2}, + } + // 1/2 * R mod p + half = common.Fp2{ + A: common.Fp{ + 0x00000000000124D6, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0xB8E0000000000000, + 0x9C8A2434C0AA7287, 0xA206996CA9A378A3, 0x6876280D41A41B52, + 0xE903B49F175CE04F, 0x0F8511860666D227, 0x00004EA07CFF6E7F}, + } + // 6*R mod p + six = common.Fp2{ + A: common.Fp{ + 0x00000000000DBA10, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x3500000000000000, + 0x3714FE4EB8399915, 0xC3A2584753EB43F4, 0xA3151D605C520428, + 0xC116CF5232C7C978, 0x49A84D4B8EFAF6AA, 0x0000305731E97514}, + } + + params = common.SidhParams{ + ID: common.Fp751, + // SIDH public key byte size. + PublicKeySize: 564, + // SIDH shared secret byte size. + SharedSecretSize: 188, + A: common.DomainParams{ + // The x-coordinate of PA + AffineP: common.Fp2{ + A: common.Fp{ + 0x884F46B74000BAA8, 0xBA52630F939DEC20, 0xC16FB97BA714A04D, + 0x082536745B1AB3DB, 0x1117157F446F9E82, 0xD2F27D621A018490, + 0x6B24AB523D544BCD, 0x9307D6AA2EA85C94, 0xE1A096729528F20F, + 0x896446F868F3255C, 0x2401D996B1BFF8A5, 0x00000EF8786A5C0A, + }, + B: common.Fp{ + 0xAEB78B3B96F59394, 0xAB26681E29C90B74, 0xE520AC30FDC4ACF1, + 0x870AAAE3A4B8111B, 0xF875BDB738D64EFF, 0x50109A7ECD7ED6BC, + 0x4CC64848FF0C56FB, 0xE617CB6C519102C9, 0x9C74B3835921E609, + 0xC91DDAE4A35A7146, 0x7FC82A155C1B9129, 0x0000214FA6B980B3, + }, + }, + // The x-coordinate of QA + AffineQ: common.Fp2{ + A: common.Fp{ + 0x0F93CC38680A8CA9, 0x762E733822E7FED7, 0xE549F005AC0ADB67, + 0x94A71FDD2C43A4ED, 0xD48645C2B04721C5, 0x432DA1FE4D4CA4DC, + 0xBC99655FAA7A80E8, 0xB2C6D502BCFD4823, 0xEE92F40CA2EC8BDB, + 0x7B074132EFB6D16C, 0x3340B46FA38A7633, 0x0000215749657F6C, + }, + B: common.Fp{ + 0xECFF375BF3079F4C, 0xFBFE74B043E80EF3, 0x17376CBE3C5C7AD1, + 0xC06327A7E29CDBF2, 0x2111649C438BF3D4, 0xC1F9298261BA2E97, + 0x1F9FECE869CFD1C2, 0x01A39B4FC9346D62, 0x147CD1D3E82A3C9F, + 0xDE84E9D249E533EE, 0x1C48A5ADFB7C578D, 0x000061ACA0B82E1D, + }, + }, + // The x-coordinate of RA = PA-QA + AffineR: common.Fp2{ + A: common.Fp{ + 0x1600C525D41059F1, 0xA596899A0A1D83F7, 0x6BFDEED6D2B23F35, + 0x5C7E707270C23910, 0x276CA1A4E8369411, 0xB193651A602925A0, + 0x243D239F1CA1F04A, 0x543DC6DA457860AD, 0xCDA590F325181DE9, + 0xD3AB7ACFDA80B395, 0x6C97468580FDDF7B, 0x0000352A3E5C4C77, + }, + B: common.Fp{ + 0x9B794F9FD1CC3EE8, 0xDB32E40A9B2FD23E, 0x26192A2542E42B67, + 0xA18E94FCA045BCE7, 0x96DC1BC38E7CDA2D, 0x9A1D91B752487DE2, + 0xCC63763987436DA3, 0x1316717AACCC551D, 0xC4C368A4632AFE72, + 0x4B6EA85C9CCD5710, 0x7A12CAD582C7BC9A, 0x00001C7E240149BF, + }, + }, + // Max size of secret key for 2-torsion group, corresponds to 2^e2 - 1 + SecretBitLen: 372, + // SecretBitLen in bytes. + SecretByteLen: 47, + // 2-torsion group computation strategy + IsogenyStrategy: []uint32{ + 0x50, 0x30, 0x1B, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, + 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x07, + 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, 0x02, 0x01, + 0x01, 0x01, 0x01, 0x0C, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02, + 0x01, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x05, 0x03, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x15, + 0x0C, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x05, 0x03, 0x02, 0x01, 0x01, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x09, 0x05, 0x03, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, + 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x21, 0x14, 0x0C, 0x07, + 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, 0x02, 0x01, + 0x01, 0x01, 0x01, 0x05, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x08, 0x05, 0x03, 0x02, 0x01, 0x01, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, + 0x01, 0x01, 0x02, 0x01, 0x01}, + }, + B: common.DomainParams{ + // The x-coordinate of PB + AffineP: common.Fp2{ + A: common.Fp{ + 0x85691AAF4015F88C, 0x7478C5B8C36E9631, 0x7EF2A185DE4DD6E2, + 0x943BBEE46BEB9DC7, 0x1A3EC62798792D22, 0x791BC4B084B31D69, + 0x03DBE6522CEA17C4, 0x04749AA65D665D83, 0x3D52B5C45EF450F3, + 0x0B4219848E36947D, 0xA4CF7070466BDE27, 0x0000334B1FA6D193, + }, + B: common.Fp{ + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + }, + }, + // The x-coordinate of QB + AffineQ: common.Fp2{ + A: common.Fp{ + 0x8E7CB3FA53211340, 0xD67CE54F7A05EEE0, 0xFDDC2C8BCE46FC38, + 0x08587FAE3110DF1E, 0xD6B8246FA22B058B, 0x4DAC3ACC905A5DBD, + 0x51D0BF2FADCED3E8, 0xE5A2406DF6484425, 0x907F177584F671B8, + 0x4738A2FFCCED051C, 0x2B0067B4177E4853, 0x00002806AC948D3D, + }, + B: common.Fp{ + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, + }, + }, + // The x-coordinate of RB = PB - QB + AffineR: common.Fp2{ + A: common.Fp{ + 0xB56457016D1D6D1C, 0x03DECCB38F39C491, 0xDFB910AC8A559452, + 0xA9D0F17D1FF24883, 0x8562BBAF515C248C, 0x249B2A6DDB1CB67D, + 0x3131AF96FB46835C, 0xE10258398480C3E1, 0xEAB5E2B872D4FAB1, + 0xB71E63875FAEB1DF, 0xF8384D4F13757CF6, 0x0000361EC9B09912, + }, + B: common.Fp{ + 0x58C967899ED16EF4, 0x81998376DC622A4B, 0x3D1C1DCFE0B12681, + 0x9347DEBB953E1730, 0x9ABB344D3A82C2D7, 0xE4881BD2820552B2, + 0x0037247923D90266, 0x2E3156EDB157E5A5, 0xF86A46A7506823F7, + 0x8FE5523A7B7F1CFC, 0xFA3CFFA38372F67B, 0x0000692DCE85FFBD, + }, + }, + // Size of secret key for 3-torsion group, corresponds to log_2(3^e3) - 1. + SecretBitLen: 378, + // SecretBitLen in bytes. + SecretByteLen: 48, + // 3-torsion group computation strategy + IsogenyStrategy: []uint32{ + 0x70, 0x3F, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, + 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, + 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, + 0x01, 0x02, 0x01, 0x01, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x1F, 0x10, 0x08, 0x04, 0x02, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, + 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x0F, 0x08, 0x04, + 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, + 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x31, 0x1F, 0x10, + 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, + 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x0F, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, + 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x07, 0x04, 0x02, 0x01, + 0x01, 0x02, 0x01, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x15, 0x0C, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x05, 0x03, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x09, 0x05, + 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01}, + }, + OneFp2: one, + HalfFp2: half, + + MsgLen: 32, + // SIKEp751 provides 128 bit of classical security ([SIKE], 5.1) + KemSize: 32, + // ceil(751+7/8) + Bytelen: 94, + CiphertextSize: 32 + 564, + InitCurve: common.ProjectiveCurveParameters{ + A: six, + C: one, + }, + } +) + +func init() { + common.Register(common.Fp751, ¶ms) +} diff --git a/dh/sidh/internal/p751/params_test.go b/dh/sidh/internal/p751/params_test.go new file mode 100644 index 0000000..bcee9ba --- /dev/null +++ b/dh/sidh/internal/p751/params_test.go @@ -0,0 +1,74 @@ +package p751 + +// Contains values used by tests +import ( + "testing/quick" + + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +var ( + expectedJ = Fp2{ + A: Fp{0xc7a8921c1fb23993, 0xa20aea321327620b, 0xf1caa17ed9676fa8, 0x61b780e6b1a04037, 0x47784af4c24acc7a, 0x83926e2e300b9adf, 0xcd891d56fae5b66, 0x49b66985beb733bc, 0xd4bcd2a473d518f, 0xe242239991abe224, 0xa8af5b20f98672f8, 0x139e4d4e4d98}, + B: Fp{0xb5b52a21f81f359, 0x715e3a865db6d920, 0x9bac2f9d8911978b, 0xef14acd8ac4c1e3d, 0xe81aacd90cfb09c8, 0xaf898288de4a09d9, 0xb85a7fb88c5c4601, 0x2c37c3f1dd303387, 0x7ad3277fe332367c, 0xd4cbee7f25a8e6f8, 0x36eacbe979eaeffa, 0x59eb5a13ac33}, + } + // A = 4385300808024233870220415655826946795549183378139271271040522089756750951667981765872679172832050962894122367066234419550072004266298327417513857609747116903999863022476533671840646615759860564818837299058134292387429068536219*i + 1408083354499944307008104531475821995920666351413327060806684084512082259107262519686546161682384352696826343970108773343853651664489352092568012759783386151707999371397181344707721407830640876552312524779901115054295865393760 + curveA = Fp2{ + A: Fp{0x8319eb18ca2c435e, 0x3a93beae72cd0267, 0x5e465e1f72fd5a84, 0x8617fa4150aa7272, 0x887da24799d62a13, 0xb079b31b3c7667fe, 0xc4661b150fa14f2e, 0xd4d2b2967bc6efd6, 0x854215a8b7239003, 0x61c5302ccba656c2, 0xf93194a27d6f97a2, 0x1ed9532bca75}, + B: Fp{0xb6f541040e8c7db6, 0x99403e7365342e15, 0x457e9cee7c29cced, 0x8ece72dc073b1d67, 0x6e73cef17ad28d28, 0x7aed836ca317472, 0x89e1de9454263b54, 0x745329277aa0071b, 0xf623dfc73bc86b9b, 0xb8e3c1d8a9245882, 0x6ad0b3d317770bec, 0x5b406e8d502b}} + + // C = 933177602672972392833143808100058748100491911694554386487433154761658932801917030685312352302083870852688835968069519091048283111836766101703759957146191882367397129269726925521881467635358356591977198680477382414690421049768*i + 9088894745865170214288643088620446862479558967886622582768682946704447519087179261631044546285104919696820250567182021319063155067584445633834024992188567423889559216759336548208016316396859149888322907914724065641454773776307 + curveC = Fp2{ + A: Fp{0x4fb2358bbf723107, 0x3a791521ac79e240, 0x283e24ef7c4c922f, 0xc89baa1205e33cc, 0x3031be81cff6fee1, 0xaf7a494a2f6a95c4, 0x248d251eaac83a1d, 0xc122fca1e2550c88, 0xbc0451b11b6cfd3d, 0x9c0a114ab046222c, 0x43b957b32f21f6ea, 0x5b9c87fa61de}, + B: Fp{0xacf142afaac15ec6, 0xfd1322a504a071d5, 0x56bb205e10f6c5c6, 0xe204d2849a97b9bd, 0x40b0122202fe7f2e, 0xecf72c6fafacf2cb, 0x45dfc681f869f60a, 0x11814c9aff4af66c, 0x9278b0c4eea54fe7, 0x9a633d5baf7f2e2e, 0x69a329e6f1a05112, 0x1d874ace23e4}} + + // x(P) = 8172151271761071554796221948801462094972242987811852753144865524899433583596839357223411088919388342364651632180452081960511516040935428737829624206426287774255114241789158000915683252363913079335550843837650671094705509470594*i + 9326574858039944121604015439381720195556183422719505497448541073272720545047742235526963773359004021838961919129020087515274115525812121436661025030481584576474033630899768377131534320053412545346268645085054880212827284581557 + affineXP = Fp2{ + A: Fp{0xe8d05f30aac47247, 0x576ec00c55441de7, 0xbf1a8ec5fe558518, 0xd77cb17f77515881, 0x8e9852837ee73ec4, 0x8159634ad4f44a6b, 0x2e4eb5533a798c5, 0x9be8c4354d5bc849, 0xf47dc61806496b84, 0x25d0e130295120e0, 0xdbef54095f8139e3, 0x5a724f20862c}, + B: Fp{0x3ca30d7623602e30, 0xfb281eddf45f07b7, 0xd2bf62d5901a45bc, 0xc67c9baf86306dd2, 0x4e2bd93093f538ca, 0xcfd92075c25b9cbe, 0xceafe9a3095bcbab, 0x7d928ad380c85414, 0x37c5f38b2afdc095, 0x75325899a7b779f4, 0xf130568249f20fdd, 0x178f264767d1}} + + // x([2]P) = 1476586462090705633631615225226507185986710728845281579274759750260315746890216330325246185232948298241128541272709769576682305216876843626191069809810990267291824247158062860010264352034514805065784938198193493333201179504845*i + 3623708673253635214546781153561465284135688791018117615357700171724097420944592557655719832228709144190233454198555848137097153934561706150196041331832421059972652530564323645509890008896574678228045006354394485640545367112224 + affineXP2 = Fp2{ + A: Fp{0x2a77afa8576ce979, 0xab1360e69b0aeba0, 0xd79e3e3cbffad660, 0x5fd0175aa10f106b, 0x1800ebafce9fbdbc, 0x228fc9142bdd6166, 0x867cf907314e34c3, 0xa58d18c94c13c31c, 0x699a5bc78b11499f, 0xa29fc29a01f7ccf1, 0x6c69c0c5347eebce, 0x38ecee0cc57}, + B: Fp{0x43607fd5f4837da0, 0x560bad4ce27f8f4a, 0x2164927f8495b4dd, 0x621103fdb831a997, 0xad740c4eea7db2db, 0x2cde0442205096cd, 0x2af51a70ede8324e, 0x41a4e680b9f3466, 0x5481f74660b8f476, 0xfcb2f3e656ff4d18, 0x42e3ce0837171acc, 0x44238c30530c}} + + // x([2^2]P) = 441719501189485559222919502512761433931671682884872259563221427434901842337947564993718830905758163254463901652874331063768876314142359813382575876106725244985607032091781306919778265250690045578695338669105227100119314831452*i + 6961734028200975729170216310486458180126343885294922940439352055937945948015840788921225114530454649744697857047401608073256634790353321931728699534700109268264491160589480994022419317695690866764726967221310990488404411684053 + affineXP4 = Fp2{ + A: Fp{0x6f9dbe4c39175153, 0xf2fec757eb99e88, 0x43d7361a93733d91, 0x3abd10ed19c85a3d, 0xc4de9ab9c5ef7181, 0x53e375901684c900, 0x68ffc3e7d71c41ff, 0x47adab62c8d942fe, 0x226a33fd6fbb381d, 0x87ef4c8fdd83309a, 0xaca1cf44c5fa8799, 0x6cbae86c755f}, + B: Fp{0x4c80c37fe68282a7, 0xbd8b9d7248bf553a, 0x1fb0e8e74d5e1762, 0xb63fa0e4e5f91482, 0xc675ab8a45a1439, 0xdfa6772deace7820, 0xf0d813d71d9a9255, 0x53a1a58c634534bd, 0x4ebfc6485fdfd888, 0x6991fe4358bcf169, 0xc0547bdaca85b6fd, 0xf461548d632}} + + // x([3^2]P) = 3957171963425208493644602380039721164492341594850197356580248639045894821895524981729970650520936632013218950972842867220898274664982599375786979902471523505057611521217523103474682939638645404445093536997296151472632038973463*i + 1357869545269286021642168835877253886774707209614159162748874474269328421720121175566245719916322684751967981171882659798149072149161259103020057556362998810229937432814792024248155991141511691087135859252304684633946087474060 + affineXP9 = Fp2{ + A: Fp{0x7c0daa0f04ded4e0, 0x52dc4f883d85e065, 0x91afbdc2c1714d0b, 0xb7b3db8e658cfeba, 0x43d4e72a692882f3, 0x535c56d83753da30, 0xc8a58724433cbf5d, 0x351153c0a5e74219, 0x2c81827d19f93dd5, 0x26ef8aca3370ea1a, 0x1cf939a6dd225dec, 0x3403cb28ad41}, + B: Fp{0x93e7bc373a9ff7b, 0x57b8cc47635ebc0f, 0x92eab55689106cf3, 0x93643111d421f24c, 0x1c58b519506f6b7a, 0xebd409fb998faa13, 0x5c86ed799d09d80e, 0xd9a1d764d6363562, 0xf95e87f92fb0c4cc, 0x6b2bbaf5632a5609, 0x2d9b6a809dfaff7f, 0x29c0460348b}} + + // Inputs for testing 3-point-ladder + threePointLadderInputs = []ProjectivePoint{ + // x(P) + { + X: Fp2{ + A: Fp{0xe8d05f30aac47247, 0x576ec00c55441de7, 0xbf1a8ec5fe558518, 0xd77cb17f77515881, 0x8e9852837ee73ec4, 0x8159634ad4f44a6b, 0x2e4eb5533a798c5, 0x9be8c4354d5bc849, 0xf47dc61806496b84, 0x25d0e130295120e0, 0xdbef54095f8139e3, 0x5a724f20862c}, + B: Fp{0x3ca30d7623602e30, 0xfb281eddf45f07b7, 0xd2bf62d5901a45bc, 0xc67c9baf86306dd2, 0x4e2bd93093f538ca, 0xcfd92075c25b9cbe, 0xceafe9a3095bcbab, 0x7d928ad380c85414, 0x37c5f38b2afdc095, 0x75325899a7b779f4, 0xf130568249f20fdd, 0x178f264767d1}}, + Z: params.OneFp2, + }, + // x(Q) + { + X: Fp2{ + A: Fp{0x2b71a2a93ad1e10e, 0xf0b9842a92cfb333, 0xae17373615a27f5c, 0x3039239f428330c4, 0xa0c4b735ed7dcf98, 0x6e359771ddf6af6a, 0xe986e4cac4584651, 0x8233a2b622d5518, 0xbfd67bf5f06b818b, 0xdffe38d0f5b966a6, 0xa86b36a3272ee00a, 0x193e2ea4f68f}, + B: Fp{0x5a0f396459d9d998, 0x479f42250b1b7dda, 0x4016b57e2a15bf75, 0xc59f915203fa3749, 0xd5f90257399cf8da, 0x1fb2dadfd86dcef4, 0x600f20e6429021dc, 0x17e347d380c57581, 0xc1b0d5fa8fe3e440, 0xbcf035330ac20e8, 0x50c2eb5f6a4f03e6, 0x86b7c4571}}, + Z: params.OneFp2, + }, + // x(P-Q) + { + X: Fp2{ + A: Fp{0x4aafa9f378f7b5ff, 0x1172a683aa8eee0, 0xea518d8cbec2c1de, 0xe191bcbb63674557, 0x97bc19637b259011, 0xdbeae5c9f4a2e454, 0x78f64d1b72a42f95, 0xe71cb4ea7e181e54, 0xe4169d4c48543994, 0x6198c2286a98730f, 0xd21d675bbab1afa5, 0x2e7269fce391}, + B: Fp{0x23355783ce1d0450, 0x683164cf4ce3d93f, 0xae6d1c4d25970fd8, 0x7807007fb80b48cf, 0xa005a62ec2bbb8a2, 0x6b5649bd016004cb, 0xbb1a13fa1330176b, 0xbf38e51087660461, 0xe577fddc5dd7b930, 0x5f38116f56947cd3, 0x3124f30b98c36fde, 0x4ca9b6e6db37}}, + Z: params.OneFp2, + }, + } + scalar3Pt = [...]uint8{84, 222, 146, 63, 85, 18, 173, 162, 167, 38, 10, 8, 143, 176, 93, 228, 247, 128, 50, 128, 205, 42, 15, 137, 119, 67, 43, 3, 61, 91, 237, 24, 235, 12, 53, 96, 186, 164, 232, 223, 197, 224, 64, 109, 137, 63, 246, 4} +) + +var quickCheckConfig = &quick.Config{ + MaxCount: (1 << 15), +} diff --git a/dh/sidh/internal/templates/arith_decl.gotemp b/dh/sidh/internal/templates/arith_decl.gotemp new file mode 100644 index 0000000..02d9063 --- /dev/null +++ b/dh/sidh/internal/templates/arith_decl.gotemp @@ -0,0 +1,45 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +// +build amd64,!noasm{{if .OPT_ARM}} arm64,!noasm{{end}} + +package {{ .PACKAGE}} + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// If choice = 0, leave x,y unchanged. If choice = 1, set x,y = y,x. +// If choice is neither 0 nor 1 then behaviour is undefined. +// This function executes in constant time. +//go:noescape +func cswap{{ .FIELD}}(x, y *Fp, choice uint8) + +// Compute z = x + y (mod p). +//go:noescape +func add{{ .FIELD}}(z, x, y *Fp) + +// Compute z = x - y (mod p). +//go:noescape +func sub{{ .FIELD}}(z, x, y *Fp) + +// Compute z = x + y, without reducing mod p. +//go:noescape +func adl{{ .FIELD}}(z, x, y *FpX2) + +// Compute z = x - y, without reducing mod p. +//go:noescape +func sul{{ .FIELD}}(z, x, y *FpX2) + +// Reduce a field element in [0, 2*p) to one in [0,p). +//go:noescape +func mod{{ .FIELD}}(x *Fp) + +// Computes z = x * y. +//go:noescape +func mul{{ .FIELD}}(z *FpX2, x, y *Fp) + +// Computes the Montgomery reduction z = x R^{-1} (mod 2*p). On return value +// of x may be changed. z=x not allowed. +//go:noescape +func rdc{{ .FIELD}}(z *Fp, x *FpX2) diff --git a/dh/sidh/internal/templates/arith_generic.gotemp b/dh/sidh/internal/templates/arith_generic.gotemp new file mode 100644 index 0000000..8e435a8 --- /dev/null +++ b/dh/sidh/internal/templates/arith_generic.gotemp @@ -0,0 +1,192 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +// +build {{if .OPT_ARM}}noasm !amd64,!arm64{{else}}noasm,arm64 !amd64{{end}} + +package {{ .PACKAGE}} + +import ( + "math/bits" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Compute z = x + y (mod p). +func add{{ .FIELD }}(z, x, y *common.Fp) { + var carry uint64 + + // z=x+y % {{ .FIELD }} + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Add64(x[i], y[i], carry) + } + + // z = z - {{ .FIELD}}x2 + carry = 0 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Sub64(z[i], {{ .FIELD}}x2[i], carry) + } + + // if z<0 add {{ .FIELD}}x2 back + mask := uint64(0 - carry) + carry = 0 + for i := 0; i < FpWords; i++ { + z[i], carry = bits.Add64(z[i], {{ .FIELD}}x2[i]&mask, carry) + } +} + +// Compute z = x - y (mod p). +func sub{{ .FIELD }}(z, x, y *common.Fp) { + var borrow uint64 + + for i := 0; i < FpWords; i++ { + z[i], borrow = bits.Sub64(x[i], y[i], borrow) + } + + mask := uint64(0 - borrow) + borrow = 0 + + for i := 0; i < FpWords; i++ { + z[i], borrow = bits.Add64(z[i], {{ .FIELD}}x2[i]&mask, borrow) + } +} + +// Conditionally swaps bits in x and y in constant time. +// mask indicates bits to be swapped (set bits are swapped) +// For details see "Hackers Delight, 2.20" +// +// Implementation doesn't actually depend on a prime field. +func cswap{{ .FIELD }}(x, y *common.Fp, mask uint8) { + var tmp, mask64 uint64 + + mask64 = 0 - uint64(mask) + for i := 0; i < FpWords; i++ { + tmp = mask64 & (x[i] ^ y[i]) + x[i] = tmp ^ x[i] + y[i] = tmp ^ y[i] + } +} + +// Perform Montgomery reduction: set z = x R^{-1} (mod 2*p) +// with R=2^(FpWords*64). Destroys the input value. +func rdc{{ .FIELD }}(z *common.Fp, x *common.FpX2) { + var carry, t, u, v uint64 + var hi, lo uint64 + var count int + + count = {{ .FIELD}}p1Zeros + + for i := 0; i < FpWords; i++ { + for j := 0; j < i; j++ { + if j < (i - count + 1) { + hi, lo = bits.Mul64(z[j], {{ .FIELD }}p1[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + } + v, carry = bits.Add64(v, x[i], 0) + u, carry = bits.Add64(u, 0, carry) + t += carry + + z[i] = v + v = u + u = t + t = 0 + } + + for i := FpWords; i < 2*FpWords-1; i++ { + if count > 0 { + count-- + } + for j := i - FpWords + 1; j < FpWords; j++ { + if j < (FpWords - count) { + hi, lo = bits.Mul64(z[j], {{ .FIELD }}p1[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + } + v, carry = bits.Add64(v, x[i], 0) + u, carry = bits.Add64(u, 0, carry) + + t += carry + z[i-FpWords] = v + v = u + u = t + t = 0 + } + v, _ = bits.Add64(v, x[2*FpWords-1], 0) + z[FpWords-1] = v +} + +// Compute z = x * y. +func mul{{ .FIELD }}(z *common.FpX2, x, y *common.Fp) { + var u, v, t uint64 + var hi, lo uint64 + var carry uint64 + + for i := uint64(0); i < FpWords; i++ { + for j := uint64(0); j <= i; j++ { + hi, lo = bits.Mul64(x[j], y[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + z[i] = v + v = u + u = t + t = 0 + } + + for i := FpWords; i < (2*FpWords)-1; i++ { + for j := i - FpWords + 1; j < FpWords; j++ { + hi, lo = bits.Mul64(x[j], y[i-j]) + v, carry = bits.Add64(lo, v, 0) + u, carry = bits.Add64(hi, u, carry) + t += carry + } + z[i] = v + v = u + u = t + t = 0 + } + z[2*FpWords-1] = v +} + +// Compute z = x + y, without reducing mod p. +func adl{{ .FIELD }}(z, x, y *common.FpX2) { + var carry uint64 + for i := 0; i < 2*FpWords; i++ { + z[i], carry = bits.Add64(x[i], y[i], carry) + } +} + +// Reduce a field element in [0, 2*p) to one in [0,p). +func mod{{ .FIELD }}(x *common.Fp) { + var borrow, mask uint64 + for i := 0; i < FpWords; i++ { + x[i], borrow = bits.Sub64(x[i], {{ .FIELD }}[i], borrow) + } + + // Sets all bits if borrow = 1 + mask = 0 - borrow + borrow = 0 + for i := 0; i < FpWords; i++ { + x[i], borrow = bits.Add64(x[i], {{ .FIELD }}[i]&mask, borrow) + } +} + +// Compute z = x - y, without reducing mod p. +func sul{{ .FIELD }}(z, x, y *common.FpX2) { + var borrow, mask uint64 + for i := 0; i < 2*FpWords; i++ { + z[i], borrow = bits.Sub64(x[i], y[i], borrow) + } + + // Sets all bits if borrow = 1 + mask = 0 - borrow + borrow = 0 + for i := FpWords; i < 2*FpWords; i++ { + z[i], borrow = bits.Add64(z[i], {{ .FIELD }}[i-FpWords]&mask, borrow) + } +} diff --git a/dh/sidh/internal/templates/arith_test.gotemp b/dh/sidh/internal/templates/arith_test.gotemp new file mode 100644 index 0000000..1ceb01e --- /dev/null +++ b/dh/sidh/internal/templates/arith_test.gotemp @@ -0,0 +1,101 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package {{ .PACKAGE}} + +import ( + "testing" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Package-level storage for this field element is intended to deter +// compiler optimizations. +var ( + benchmarkFp common.Fp + benchmarkFpX2 common.FpX2 + bench_x = common.Fp{17026702066521327207, 5108203422050077993, 10225396685796065916, 11153620995215874678, 6531160855165088358, 15302925148404145445, 1248821577836769963, 9789766903037985294, 7493111552032041328, 10838999828319306046, 18103257655515297935, 27403304611634} + bench_y = common.Fp{4227467157325093378, 10699492810770426363, 13500940151395637365, 12966403950118934952, 16517692605450415877, 13647111148905630666, 14223628886152717087, 7167843152346903316, 15855377759596736571, 4300673881383687338, 6635288001920617779, 30486099554235} + bench_z = common.FpX2{1595347748594595712, 10854920567160033970, 16877102267020034574, 12435724995376660096, 3757940912203224231, 8251999420280413600, 3648859773438820227, 17622716832674727914, 11029567000887241528, 11216190007549447055, 17606662790980286987, 4720707159513626555, 12887743598335030915, 14954645239176589309, 14178817688915225254, 1191346797768989683, 12629157932334713723, 6348851952904485603, 16444232588597434895, 7809979927681678066, 14642637672942531613, 3092657597757640067, 10160361564485285723, 240071237} +) + +func TestFpCswap(t *testing.T) { + var one = common.Fp{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + var two = common.Fp{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} + + var x = one + var y = two + + cswap{{ .FIELD}}(&x, &y, 0) + for i := 0; i < FpWords; i++ { + if (x[i] != one[i]) || (y[i] != two[i]) { + t.Error("Found", x, "expected", two) + } + } + + cswap{{ .FIELD}}(&x, &y, 1) + for i := 0; i < FpWords; i++ { + if (x[i] != two[i]) || (y[i] != one[i]) { + t.Error("Found", x, "expected", two) + } + } +} + +// Benchmarking for field arithmetic +func BenchmarkMul(b *testing.B) { + for n := 0; n < b.N; n++ { + mul{{ .FIELD}}(&benchmarkFpX2, &bench_x, &bench_y) + } +} + +func BenchmarkRdc(b *testing.B) { + z := bench_z + + // This benchmark actually computes garbage, because + // rdc{{ .FIELD}} mangles its input, but since it's + // constant-time that shouldn't matter for the benchmarks. + for n := 0; n < b.N; n++ { + rdc{{ .FIELD}}(&benchmarkFp, &z) + } +} + +func BenchmarkAdd(b *testing.B) { + for n := 0; n < b.N; n++ { + add{{ .FIELD}}(&benchmarkFp, &bench_x, &bench_y) + } +} + +func BenchmarkSub(b *testing.B) { + for n := 0; n < b.N; n++ { + sub{{ .FIELD}}(&benchmarkFp, &bench_x, &bench_y) + } +} + +func BenchmarkCswap(b *testing.B) { + x, y := bench_x, bench_y + for n := 0; n < b.N; n++ { + cswap{{ .FIELD}}(&x, &y, 1) + cswap{{ .FIELD}}(&x, &y, 0) + } +} + +func BenchmarkMod(b *testing.B) { + x := bench_x + for n := 0; n < b.N; n++ { + mod{{ .FIELD}}(&x) + } +} + +func BenchmarkX2AddLazy(b *testing.B) { + x, y, z := bench_z, bench_z, bench_z + for n := 0; n < b.N; n++ { + adl{{ .FIELD}}(&x, &y, &z) + } +} + +func BenchmarkX2SubLazy(b *testing.B) { + x, y, z := bench_z, bench_z, bench_z + for n := 0; n < b.N; n++ { + sul{{ .FIELD}}(&x, &y, &z) + } +} diff --git a/dh/sidh/internal/templates/core.gotemp b/dh/sidh/internal/templates/core.gotemp new file mode 100644 index 0000000..0e70380 --- /dev/null +++ b/dh/sidh/internal/templates/core.gotemp @@ -0,0 +1,282 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package {{ .PACKAGE}} + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// ----------------------------------------------------------------------------- +// Functions for traversing isogeny trees acoording to strategy. Key type 'A' is +// + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreePublicKeyA(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny4 + + cparam := CalcCurveParamsEquiv4(curve) + strat := params.A.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow2k(xR, &cparam, 2*k) + i += int(k) + } + cparam = phi.GenerateCurve(xR) + + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + *phiP = phi.EvaluatePoint(phiP) + *phiQ = phi.EvaluatePoint(phiQ) + *phiR = phi.EvaluatePoint(phiR) + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR needed +// for public key generation. +func traverseTreeSharedKeyA(curve *ProjectiveCurveParameters, xR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny4 + + cparam := CalcCurveParamsEquiv4(curve) + strat := params.A.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow2k(xR, &cparam, 2*k) + i += int(k) + } + cparam = phi.GenerateCurve(xR) + + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreePublicKeyB(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny3 + + cparam := CalcCurveParamsEquiv3(curve) + strat := params.B.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow3k(xR, &cparam, k) + i += int(k) + } + + cparam = phi.GenerateCurve(xR) + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + *phiP = phi.EvaluatePoint(phiP) + *phiQ = phi.EvaluatePoint(phiQ) + *phiR = phi.EvaluatePoint(phiR) + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed +// for public key generation. +func traverseTreeSharedKeyB(curve *ProjectiveCurveParameters, xR *ProjectivePoint) { + var points = make([]ProjectivePoint, 0, 8) + var indices = make([]int, 0, 8) + var i, sIdx int + var phi isogeny3 + + cparam := CalcCurveParamsEquiv3(curve) + strat := params.B.IsogenyStrategy + stratSz := len(strat) + + for j := 1; j <= stratSz; j++ { + for i <= stratSz-j { + points = append(points, *xR) + indices = append(indices, i) + + k := strat[sIdx] + sIdx++ + Pow3k(xR, &cparam, k) + i += int(k) + } + + cparam = phi.GenerateCurve(xR) + for k := 0; k < len(points); k++ { + points[k] = phi.EvaluatePoint(&points[k]) + } + + // pop xR from points + *xR, points = points[len(points)-1], points[:len(points)-1] + i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + } +} + +// Generate a public key in the 2-torsion group. Public key is a set +// of three x-coordinates: xP,xQ,x(P-Q), where P,Q are points on E_a(Fp2) +func PublicKeyGenA(pub3Pt *[3]Fp2, prvBytes []byte) { + var xPA, xQA, xRA ProjectivePoint + var xPB, xQB, xRB, xR ProjectivePoint + var invZP, invZQ, invZR Fp2 + var phi isogeny4 + + // Load points for A + xPA = ProjectivePoint{X: params.A.AffineP, Z: params.OneFp2} + xQA = ProjectivePoint{X: params.A.AffineQ, Z: params.OneFp2} + xRA = ProjectivePoint{X: params.A.AffineR, Z: params.OneFp2} + + // Load points for B + xRB = ProjectivePoint{X: params.B.AffineR, Z: params.OneFp2} + xQB = ProjectivePoint{X: params.B.AffineQ, Z: params.OneFp2} + xPB = ProjectivePoint{X: params.B.AffineP, Z: params.OneFp2} + + // Find isogeny kernel + xR = ScalarMul3Pt(¶ms.InitCurve, &xPA, &xQA, &xRA, params.A.SecretBitLen, prvBytes) + traverseTreePublicKeyA(¶ms.InitCurve, &xR, &xPB, &xQB, &xRB) + + // Secret isogeny + phi.GenerateCurve(&xR) + xPA = phi.EvaluatePoint(&xPB) + xQA = phi.EvaluatePoint(&xQB) + xRA = phi.EvaluatePoint(&xRB) + Fp2Batch3Inv(&xPA.Z, &xQA.Z, &xRA.Z, &invZP, &invZQ, &invZR) + + mul(&pub3Pt[0], &xPA.X, &invZP) + mul(&pub3Pt[1], &xQA.X, &invZQ) + mul(&pub3Pt[2], &xRA.X, &invZR) +} + +// Generate a public key in the 2-torsion group. Public key is a set +// of three x-coordinates: xP,xQ,x(P-Q), where P,Q are points on E_a(Fp2) +func PublicKeyGenB(pub3Pt *[3]Fp2, prvBytes []byte) { + var xPB, xQB, xRB, xR ProjectivePoint + var xPA, xQA, xRA ProjectivePoint + var invZP, invZQ, invZR Fp2 + var phi isogeny3 + + // Load points for B + xRB = ProjectivePoint{X: params.B.AffineR, Z: params.OneFp2} + xQB = ProjectivePoint{X: params.B.AffineQ, Z: params.OneFp2} + xPB = ProjectivePoint{X: params.B.AffineP, Z: params.OneFp2} + + // Load points for A + xPA = ProjectivePoint{X: params.A.AffineP, Z: params.OneFp2} + xQA = ProjectivePoint{X: params.A.AffineQ, Z: params.OneFp2} + xRA = ProjectivePoint{X: params.A.AffineR, Z: params.OneFp2} + + // Find isogeny kernel + xR = ScalarMul3Pt(¶ms.InitCurve, &xPB, &xQB, &xRB, params.B.SecretBitLen, prvBytes) + traverseTreePublicKeyB(¶ms.InitCurve, &xR, &xPA, &xQA, &xRA) + + phi.GenerateCurve(&xR) + xPB = phi.EvaluatePoint(&xPA) + xQB = phi.EvaluatePoint(&xQA) + xRB = phi.EvaluatePoint(&xRA) + Fp2Batch3Inv(&xPB.Z, &xQB.Z, &xRB.Z, &invZP, &invZQ, &invZR) + + mul(&pub3Pt[0], &xPB.X, &invZP) + mul(&pub3Pt[1], &xQB.X, &invZQ) + mul(&pub3Pt[2], &xRB.X, &invZR) +} + +// ----------------------------------------------------------------------------- +// Key agreement functions +// + +// Establishing shared keys in in 2-torsion group +func DeriveSecretA(ss, prv []byte, pub3Pt *[3]Fp2) { + var xP, xQ, xQmP ProjectivePoint + var xR ProjectivePoint + var phi isogeny4 + var jInv Fp2 + + // Recover curve coefficients + cparam := params.InitCurve + RecoverCoordinateA(&cparam, &pub3Pt[0], &pub3Pt[1], &pub3Pt[2]) + + // Find kernel of the morphism + xP = ProjectivePoint{X: pub3Pt[0], Z: params.OneFp2} + xQ = ProjectivePoint{X: pub3Pt[1], Z: params.OneFp2} + xQmP = ProjectivePoint{X: pub3Pt[2], Z: params.OneFp2} + xR = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, params.A.SecretBitLen, prv) + + // Traverse isogeny tree + traverseTreeSharedKeyA(&cparam, &xR) + + // Calculate j-invariant on isogeneus curve + c := phi.GenerateCurve(&xR) + RecoverCurveCoefficients4(&cparam, &c) + Jinvariant(&cparam, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(ss, &jInv, params.Bytelen) +} + +// Establishing shared keys in in 3-torsion group +func DeriveSecretB(ss, prv []byte, pub3Pt *[3]Fp2) { + var xP, xQ, xQmP ProjectivePoint + var xR ProjectivePoint + var phi isogeny3 + var jInv Fp2 + + // Recover curve coefficients + cparam := params.InitCurve + RecoverCoordinateA(&cparam, &pub3Pt[0], &pub3Pt[1], &pub3Pt[2]) + + // Find kernel of the morphism + xP = ProjectivePoint{X: pub3Pt[0], Z: params.OneFp2} + xQ = ProjectivePoint{X: pub3Pt[1], Z: params.OneFp2} + xQmP = ProjectivePoint{X: pub3Pt[2], Z: params.OneFp2} + xR = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, params.B.SecretBitLen, prv) + + // Traverse isogeny tree + traverseTreeSharedKeyB(&cparam, &xR) + + // Calculate j-invariant on isogeneus curve + c := phi.GenerateCurve(&xR) + RecoverCurveCoefficients3(&cparam, &c) + Jinvariant(&cparam, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(ss, &jInv, params.Bytelen) +} diff --git a/dh/sidh/internal/templates/curve.gotemp b/dh/sidh/internal/templates/curve.gotemp new file mode 100644 index 0000000..92ec240 --- /dev/null +++ b/dh/sidh/internal/templates/curve.gotemp @@ -0,0 +1,362 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package {{ .PACKAGE}} + +import ( + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Stores isogeny 3 curve constants +type isogeny3 struct { + K1 Fp2 + K2 Fp2 +} + +// Stores isogeny 4 curve constants +type isogeny4 struct { + isogeny3 + K3 Fp2 +} + +// Computes j-invariant for a curve y2=x3+A/Cx+x with A,C in F_(p^2). Result +// is returned in jBytes buffer, encoded in little-endian format. Caller +// provided jBytes buffer has to be big enough to j-invariant value. In case +// of SIDH, buffer size must be at least size of shared secret. +// Implementation corresponds to Algorithm 9 from SIKE. +func Jinvariant(cparams *ProjectiveCurveParameters, j *Fp2) { + var t0, t1 Fp2 + + sqr(j, &cparams.A) // j = A^2 + sqr(&t1, &cparams.C) // t1 = C^2 + add(&t0, &t1, &t1) // t0 = t1 + t1 + sub(&t0, j, &t0) // t0 = j - t0 + sub(&t0, &t0, &t1) // t0 = t0 - t1 + sub(j, &t0, &t1) // t0 = t0 - t1 + sqr(&t1, &t1) // t1 = t1^2 + mul(j, j, &t1) // j = j * t1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t0, &t0, &t0) // t0 = t0 + t0 + sqr(&t1, &t0) // t1 = t0^2 + mul(&t0, &t0, &t1) // t0 = t0 * t1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t0, &t0, &t0) // t0 = t0 + t0 + inv(j, j) // j = 1/j + mul(j, &t0, j) // j = t0 * j +} + +// Given affine points x(P), x(Q) and x(Q-P) in a extension field F_{p^2}, function +// recorvers projective coordinate A of a curve. This is Algorithm 10 from SIKE. +func RecoverCoordinateA(curve *ProjectiveCurveParameters, xp, xq, xr *Fp2) { + var t0, t1 Fp2 + + add(&t1, xp, xq) // t1 = Xp + Xq + mul(&t0, xp, xq) // t0 = Xp * Xq + mul(&curve.A, xr, &t1) // A = X(q-p) * t1 + add(&curve.A, &curve.A, &t0) // A = A + t0 + mul(&t0, &t0, xr) // t0 = t0 * X(q-p) + sub(&curve.A, &curve.A, ¶ms.OneFp2) // A = A - 1 + add(&t0, &t0, &t0) // t0 = t0 + t0 + add(&t1, &t1, xr) // t1 = t1 + X(q-p) + add(&t0, &t0, &t0) // t0 = t0 + t0 + sqr(&curve.A, &curve.A) // A = A^2 + inv(&t0, &t0) // t0 = 1/t0 + mul(&curve.A, &curve.A, &t0) // A = A * t0 + sub(&curve.A, &curve.A, &t1) // A = A - t1 +} + +// Computes equivalence (A:C) ~ (A+2C : A-2C) +func CalcCurveParamsEquiv3(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv { + var coef CurveCoefficientsEquiv + var c2 Fp2 + + add(&c2, &cparams.C, &cparams.C) + // A24p = A+2*C + add(&coef.A, &cparams.A, &c2) + // A24m = A-2*C + sub(&coef.C, &cparams.A, &c2) + return coef +} + +// Computes equivalence (A:C) ~ (A+2C : 4C) +func CalcCurveParamsEquiv4(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv { + var coefEq CurveCoefficientsEquiv + + add(&coefEq.C, &cparams.C, &cparams.C) + // A24p = A+2C + add(&coefEq.A, &cparams.A, &coefEq.C) + // C24 = 4*C + add(&coefEq.C, &coefEq.C, &coefEq.C) + return coefEq +} + +// Helper function for RightToLeftLadder(). Returns A+2C / 4. +func CalcAplus2Over4(cparams *ProjectiveCurveParameters) (ret Fp2) { + var tmp Fp2 + + // 2C + add(&tmp, &cparams.C, &cparams.C) + // A+2C + add(&ret, &cparams.A, &tmp) + // 1/4C + add(&tmp, &tmp, &tmp) + inv(&tmp, &tmp) + // A+2C/4C + mul(&ret, &ret, &tmp) + return +} + +// Recovers (A:C) curve parameters from projectively equivalent (A+2C:A-2C). +func RecoverCurveCoefficients3(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) { + add(&cparams.A, &coefEq.A, &coefEq.C) + // cparams.A = 2*(A+2C+A-2C) = 4A + add(&cparams.A, &cparams.A, &cparams.A) + // cparams.C = (A+2C-A+2C) = 4C + sub(&cparams.C, &coefEq.A, &coefEq.C) + return +} + +// Recovers (A:C) curve parameters from projectively equivalent (A+2C:4C). +func RecoverCurveCoefficients4(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) { + // cparams.C = (4C)*1/2=2C + mul(&cparams.C, &coefEq.C, ¶ms.HalfFp2) + // cparams.A = A+2C - 2C = A + sub(&cparams.A, &coefEq.A, &cparams.C) + // cparams.C = 2C * 1/2 = C + mul(&cparams.C, &cparams.C, ¶ms.HalfFp2) +} + +// Combined coordinate doubling and differential addition. Takes projective points +// P,Q,Q-P and (A+2C)/4C curve E coefficient. Returns 2*P and P+Q calculated on E. +// Function is used only by RightToLeftLadder. Corresponds to Algorithm 5 of SIKE +func xDbladd(P, Q, QmP *ProjectivePoint, a24 *Fp2) (dblP, PaQ ProjectivePoint) { + var t0, t1, t2 Fp2 + + xQmP, zQmP := &QmP.X, &QmP.Z + xPaQ, zPaQ := &PaQ.X, &PaQ.Z + x2P, z2P := &dblP.X, &dblP.Z + xP, zP := &P.X, &P.Z + xQ, zQ := &Q.X, &Q.Z + + add(&t0, xP, zP) // t0 = Xp+Zp + sub(&t1, xP, zP) // t1 = Xp-Zp + sqr(x2P, &t0) // 2P.X = t0^2 + sub(&t2, xQ, zQ) // t2 = Xq-Zq + add(xPaQ, xQ, zQ) // Xp+q = Xq+Zq + mul(&t0, &t0, &t2) // t0 = t0 * t2 + mul(z2P, &t1, &t1) // 2P.Z = t1 * t1 + mul(&t1, &t1, xPaQ) // t1 = t1 * Xp+q + sub(&t2, x2P, z2P) // t2 = 2P.X - 2P.Z + mul(x2P, x2P, z2P) // 2P.X = 2P.X * 2P.Z + mul(xPaQ, a24, &t2) // Xp+q = A24 * t2 + sub(zPaQ, &t0, &t1) // Zp+q = t0 - t1 + add(z2P, xPaQ, z2P) // 2P.Z = Xp+q + 2P.Z + add(xPaQ, &t0, &t1) // Xp+q = t0 + t1 + mul(z2P, z2P, &t2) // 2P.Z = 2P.Z * t2 + sqr(zPaQ, zPaQ) // Zp+q = Zp+q ^ 2 + sqr(xPaQ, xPaQ) // Xp+q = Xp+q ^ 2 + mul(zPaQ, xQmP, zPaQ) // Zp+q = Xq-p * Zp+q + mul(xPaQ, zQmP, xPaQ) // Xp+q = Zq-p * Xp+q + return +} + +// Given the curve parameters, xP = x(P), computes xP = x([2^k]P) +// Safe to overlap xP, x2P. +func Pow2k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) { + var t0, t1 Fp2 + + x, z := &xP.X, &xP.Z + for i := uint32(0); i < k; i++ { + sub(&t0, x, z) // t0 = Xp - Zp + add(&t1, x, z) // t1 = Xp + Zp + sqr(&t0, &t0) // t0 = t0 ^ 2 + sqr(&t1, &t1) // t1 = t1 ^ 2 + mul(z, ¶ms.C, &t0) // Z2p = C24 * t0 + mul(x, z, &t1) // X2p = Z2p * t1 + sub(&t1, &t1, &t0) // t1 = t1 - t0 + mul(&t0, ¶ms.A, &t1) // t0 = A24+ * t1 + add(z, z, &t0) // Z2p = Z2p + t0 + mul(z, z, &t1) // Zp = Z2p * t1 + } +} + +// Given the curve parameters, xP = x(P), and k >= 0, compute xP = x([3^k]P). +// +// Safe to overlap xP, xR. +func Pow3k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) { + var t0, t1, t2, t3, t4, t5, t6 Fp2 + + x, z := &xP.X, &xP.Z + for i := uint32(0); i < k; i++ { + sub(&t0, x, z) // t0 = Xp - Zp + sqr(&t2, &t0) // t2 = t0^2 + add(&t1, x, z) // t1 = Xp + Zp + sqr(&t3, &t1) // t3 = t1^2 + add(&t4, &t1, &t0) // t4 = t1 + t0 + sub(&t0, &t1, &t0) // t0 = t1 - t0 + sqr(&t1, &t4) // t1 = t4^2 + sub(&t1, &t1, &t3) // t1 = t1 - t3 + sub(&t1, &t1, &t2) // t1 = t1 - t2 + mul(&t5, &t3, ¶ms.A) // t5 = t3 * A24+ + mul(&t3, &t3, &t5) // t3 = t5 * t3 + mul(&t6, &t2, ¶ms.C) // t6 = t2 * A24- + mul(&t2, &t2, &t6) // t2 = t2 * t6 + sub(&t3, &t2, &t3) // t3 = t2 - t3 + sub(&t2, &t5, &t6) // t2 = t5 - t6 + mul(&t1, &t2, &t1) // t1 = t2 * t1 + add(&t2, &t3, &t1) // t2 = t3 + t1 + sqr(&t2, &t2) // t2 = t2^2 + mul(x, &t2, &t4) // X3p = t2 * t4 + sub(&t1, &t3, &t1) // t1 = t3 - t1 + sqr(&t1, &t1) // t1 = t1^2 + mul(z, &t1, &t0) // Z3p = t1 * t0 + } +} + +// Set (y1, y2, y3) = (1/x1, 1/x2, 1/x3). +// +// All xi, yi must be distinct. +func Fp2Batch3Inv(x1, x2, x3, y1, y2, y3 *Fp2) { + var x1x2, t Fp2 + + mul(&x1x2, x1, x2) // x1*x2 + mul(&t, &x1x2, x3) // 1/(x1*x2*x3) + inv(&t, &t) + mul(y1, &t, x2) // 1/x1 + mul(y1, y1, x3) + mul(y2, &t, x1) // 1/x2 + mul(y2, y2, x3) + mul(y3, &t, &x1x2) // 1/x3 +} + +// Scalarmul3Pt is a right-to-left point multiplication that given the +// x-coordinate of P, Q and P-Q calculates the x-coordinate of R=Q+[scalar]P. +// nbits must be smaller or equal to len(scalar). +func ScalarMul3Pt(cparams *ProjectiveCurveParameters, P, Q, PmQ *ProjectivePoint, nbits uint, scalar []uint8) ProjectivePoint { + var R0, R2, R1 ProjectivePoint + aPlus2Over4 := CalcAplus2Over4(cparams) + R1 = *P + R2 = *PmQ + R0 = *Q + + // Iterate over the bits of the scalar, bottom to top + prevBit := uint8(0) + for i := uint(0); i < nbits; i++ { + bit := (scalar[i>>3] >> (i & 7) & 1) + swap := prevBit ^ bit + prevBit = bit + cswap(&R1.X, &R1.Z, &R2.X, &R2.Z, swap) + R0, R2 = xDbladd(&R0, &R2, &R1, &aPlus2Over4) + } + cswap(&R1.X, &R1.Z, &R2.X, &R2.Z, prevBit) + return R1 +} + +// Given a three-torsion point p = x(PB) on the curve E_(A:C), construct the +// three-isogeny phi : E_(A:C) -> E_(A:C)/ = E_(A':C'). +// +// Input: (XP_3: ZP_3), where P_3 has exact order 3 on E_A/C +// Output: * Curve coordinates (A' + 2C', A' - 2C') corresponding to E_A'/C' = A_E/C/ +// * Isogeny phi with constants in F_p^2 +func (phi *isogeny3) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv { + var t0, t1, t2, t3, t4 Fp2 + var coefEq CurveCoefficientsEquiv + var K1, K2 = &phi.K1, &phi.K2 + + sub(K1, &p.X, &p.Z) // K1 = XP3 - ZP3 + sqr(&t0, K1) // t0 = K1^2 + add(K2, &p.X, &p.Z) // K2 = XP3 + ZP3 + sqr(&t1, K2) // t1 = K2^2 + add(&t2, &t0, &t1) // t2 = t0 + t1 + add(&t3, K1, K2) // t3 = K1 + K2 + sqr(&t3, &t3) // t3 = t3^2 + sub(&t3, &t3, &t2) // t3 = t3 - t2 + add(&t2, &t1, &t3) // t2 = t1 + t3 + add(&t3, &t3, &t0) // t3 = t3 + t0 + add(&t4, &t3, &t0) // t4 = t3 + t0 + add(&t4, &t4, &t4) // t4 = t4 + t4 + add(&t4, &t1, &t4) // t4 = t1 + t4 + mul(&coefEq.C, &t2, &t4) // A24m = t2 * t4 + add(&t4, &t1, &t2) // t4 = t1 + t2 + add(&t4, &t4, &t4) // t4 = t4 + t4 + add(&t4, &t0, &t4) // t4 = t0 + t4 + mul(&t4, &t3, &t4) // t4 = t3 * t4 + sub(&t0, &t4, &coefEq.C) // t0 = t4 - A24m + add(&coefEq.A, &coefEq.C, &t0) // A24p = A24m + t0 + return coefEq +} + +// Given a 3-isogeny phi and a point pB = x(PB), compute x(QB), the x-coordinate +// of the image QB = phi(PB) of PB under phi : E_(A:C) -> E_(A':C'). +// +// The output xQ = x(Q) is then a point on the curve E_(A':C'); the curve +// parameters are returned by the GenerateCurve function used to construct phi. +func (phi *isogeny3) EvaluatePoint(p *ProjectivePoint) ProjectivePoint { + var t0, t1, t2 Fp2 + var q ProjectivePoint + var K1, K2 = &phi.K1, &phi.K2 + var px, pz = &p.X, &p.Z + + add(&t0, px, pz) // t0 = XQ + ZQ + sub(&t1, px, pz) // t1 = XQ - ZQ + mul(&t0, K1, &t0) // t2 = K1 * t0 + mul(&t1, K2, &t1) // t1 = K2 * t1 + add(&t2, &t0, &t1) // t2 = t0 + t1 + sub(&t0, &t1, &t0) // t0 = t1 - t0 + sqr(&t2, &t2) // t2 = t2 ^ 2 + sqr(&t0, &t0) // t0 = t0 ^ 2 + mul(&q.X, px, &t2) // XQ'= XQ * t2 + mul(&q.Z, pz, &t0) // ZQ'= ZQ * t0 + return q +} + +// Given a four-torsion point p = x(PB) on the curve E_(A:C), construct the +// four-isogeny phi : E_(A:C) -> E_(A:C)/ = E_(A':C'). +// +// Input: (XP_4: ZP_4), where P_4 has exact order 4 on E_A/C +// Output: * Curve coordinates (A' + 2C', 4C') corresponding to E_A'/C' = A_E/C/ +// * Isogeny phi with constants in F_p^2 +func (phi *isogeny4) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv { + var coefEq CurveCoefficientsEquiv + var xp4, zp4 = &p.X, &p.Z + var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3 + + sub(K2, xp4, zp4) + add(K3, xp4, zp4) + sqr(K1, zp4) + add(K1, K1, K1) + sqr(&coefEq.C, K1) + add(K1, K1, K1) + sqr(&coefEq.A, xp4) + add(&coefEq.A, &coefEq.A, &coefEq.A) + sqr(&coefEq.A, &coefEq.A) + return coefEq +} + +// Given a 4-isogeny phi and a point xP = x(P), compute x(Q), the x-coordinate +// of the image Q = phi(P) of P under phi : E_(A:C) -> E_(A':C'). +// +// Input: Isogeny returned by GenerateCurve and point q=(Qx,Qz) from E0_A/C +// Output: Corresponding point q from E1_A'/C', where E1 is 4-isogenous to E0 +func (phi *isogeny4) EvaluatePoint(p *ProjectivePoint) ProjectivePoint { + var t0, t1 Fp2 + var q = *p + var xq, zq = &q.X, &q.Z + var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3 + + add(&t0, xq, zq) + sub(&t1, xq, zq) + mul(xq, &t0, K2) + mul(zq, &t1, K3) + mul(&t0, &t0, &t1) + mul(&t0, &t0, K1) + add(&t1, xq, zq) + sub(zq, xq, zq) + sqr(&t1, &t1) + sqr(zq, zq) + add(xq, &t0, &t1) + sub(&t0, zq, &t0) + mul(xq, xq, &t1) + mul(zq, zq, &t0) + return q +} diff --git a/dh/sidh/internal/templates/curve_test.gotemp b/dh/sidh/internal/templates/curve_test.gotemp new file mode 100644 index 0000000..5c504f3 --- /dev/null +++ b/dh/sidh/internal/templates/curve_test.gotemp @@ -0,0 +1,100 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package {{ .PACKAGE}} + +import ( + "bytes" + "testing" + + . "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +func vartimeEqProjFp2(lhs, rhs *ProjectivePoint) bool { + var t0, t1 Fp2 + mul(&t0, &lhs.X, &rhs.Z) + mul(&t1, &lhs.Z, &rhs.X) + return vartimeEqFp2(&t0, &t1) +} + +func toAffine(point *ProjectivePoint) *Fp2 { + var affineX Fp2 + inv(&affineX, &point.Z) + mul(&affineX, &affineX, &point.X) + return &affineX +} + +func Test_jInvariant(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var jbufRes = make([]byte, params.SharedSecretSize) + var jbufExp = make([]byte, params.SharedSecretSize) + var jInv Fp2 + + Jinvariant(&curve, &jInv) + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(jbufRes, &jInv, params.Bytelen) + + jInv = expectedJ + FromMontgomery(&jInv, &jInv) + Fp2ToBytes(jbufExp, &jInv, params.Bytelen) + + if !bytes.Equal(jbufRes[:], jbufExp[:]) { + t.Error("Computed incorrect j-invariant: found\n", jbufRes, "\nexpected\n", jbufExp) + } +} + +func TestProjectivePointVartimeEq(t *testing.T) { + var xP ProjectivePoint + + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + xQ := xP + + // Scale xQ, which results in the same projective point + mul(&xQ.X, &xQ.X, &curveA) + mul(&xQ.Z, &xQ.Z, &curveA) + if !vartimeEqProjFp2(&xP, &xQ) { + t.Error("Expected the scaled point to be equal to the original") + } +} + +func TestPointMulVersusSage(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var cparams = CalcCurveParamsEquiv4(&curve) + var xP ProjectivePoint + + // x 2 + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow2k(&xP, &cparams, 1) + afxQ := toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP2) { + t.Error("\nExpected\n", affineXP2, "\nfound\n", afxQ) + } + + // x 4 + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow2k(&xP, &cparams, 2) + afxQ = toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP4) { + t.Error("\nExpected\n", affineXP4, "\nfound\n", afxQ) + } +} + +func TestPointMul9VersusSage(t *testing.T) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + var cparams = CalcCurveParamsEquiv3(&curve) + var xP ProjectivePoint + + xP = ProjectivePoint{X: affineXP, Z: params.OneFp2} + Pow3k(&xP, &cparams, 2) + afxQ := toAffine(&xP) + if !vartimeEqFp2(afxQ, &affineXP9) { + t.Error("\nExpected\n", affineXP9, "\nfound\n", afxQ) + } +} + +func BenchmarkThreePointLadder(b *testing.B) { + var curve = ProjectiveCurveParameters{A: curveA, C: curveC} + for n := 0; n < b.N; n++ { + ScalarMul3Pt(&curve, &threePointLadderInputs[0], &threePointLadderInputs[1], &threePointLadderInputs[2], uint(len(scalar3Pt)*8), scalar3Pt[:]) + } +} diff --git a/dh/sidh/internal/templates/fp2.gotemp b/dh/sidh/internal/templates/fp2.gotemp new file mode 100644 index 0000000..2505735 --- /dev/null +++ b/dh/sidh/internal/templates/fp2.gotemp @@ -0,0 +1,195 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package {{ .PACKAGE}} + +import ( + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +// Montgomery multiplication. Input values must be already +// in Montgomery domain. +func mulP(dest, lhs, rhs *common.Fp) { + var ab common.FpX2 + mul{{ .FIELD}}(&ab, lhs, rhs) // = a*b*R*R + rdc{{ .FIELD}}(dest, &ab) // = a*b*R mod p +} + +// Set dest = x^((p-3)/4). If x is square, this is 1/sqrt(x). +// Uses variation of sliding-window algorithm from with window size +// of 5 and least to most significant bit sliding (left-to-right) +// See HAC 14.85 for general description. +// +// Allowed to overlap x with dest. +// All values in Montgomery domains +// Set dest = x^(2^k), for k >= 1, by repeated squarings. +func p34(dest, x *common.Fp) { + var lookup [16]common.Fp + + // This performs sum(powStrategy) + 1 squarings and len(lookup) + len(mulStrategy) + // multiplications. + powStrategy := {{ .P34_POW_STRATEGY}} + mulStrategy := {{ .P34_MUL_STRATEGY}} + initialMul := uint8({{ .P34_INITIAL_MUL}}) + + // Precompute lookup table of odd multiples of x for window + // size k=5. + var xx common.Fp + mulP(&xx, x, x) + lookup[0] = *x + for i := 1; i < 16; i++ { + mulP(&lookup[i], &lookup[i-1], &xx) + } + + // Now lookup = {x, x^3, x^5, ... } + // so that lookup[i] = x^{2*i + 1} + // so that lookup[k/2] = x^k, for odd k + *dest = lookup[initialMul] + for i := uint8(0); i < uint8(len(powStrategy)); i++ { + mulP(dest, dest, dest) + for j := uint8(1); j < powStrategy[i]; j++ { + mulP(dest, dest, dest) + } + mulP(dest, dest, &lookup[mulStrategy[i]]) + } +} + +func add(dest, lhs, rhs *common.Fp2) { + add{{ .FIELD}}(&dest.A, &lhs.A, &rhs.A) + add{{ .FIELD}}(&dest.B, &lhs.B, &rhs.B) +} + +func sub(dest, lhs, rhs *common.Fp2) { + sub{{ .FIELD}}(&dest.A, &lhs.A, &rhs.A) + sub{{ .FIELD}}(&dest.B, &lhs.B, &rhs.B) +} + +func mul(dest, lhs, rhs *common.Fp2) { + var bMinA, cMinD common.Fp + var ac, bd common.FpX2 + var adPlusBc common.FpX2 + var acMinBd common.FpX2 + + // Let (a,b,c,d) = (lhs.a,lhs.b,rhs.a,rhs.b). + // + // (a + bi)*(c + di) = (a*c - b*d) + (a*d + b*c)i + // + // Use Karatsuba's trick: note that + // + // (b - a)*(c - d) = (b*c + a*d) - a*c - b*d + // + // so (a*d + b*c) = (b-a)*(c-d) + a*c + b*d. + mul{{ .FIELD}}(&ac, &lhs.A, &rhs.A) // = a*c*R*R + mul{{ .FIELD}}(&bd, &lhs.B, &rhs.B) // = b*d*R*R + sub{{ .FIELD}}(&bMinA, &lhs.B, &lhs.A) // = (b-a)*R + sub{{ .FIELD}}(&cMinD, &rhs.A, &rhs.B) // = (c-d)*R + mul{{ .FIELD}}(&adPlusBc, &bMinA, &cMinD) // = (b-a)*(c-d)*R*R + adl{{ .FIELD}}(&adPlusBc, &adPlusBc, &ac) // = ((b-a)*(c-d) + a*c)*R*R + adl{{ .FIELD}}(&adPlusBc, &adPlusBc, &bd) // = ((b-a)*(c-d) + a*c + b*d)*R*R + rdc{{ .FIELD}}(&dest.B, &adPlusBc) // = (a*d + b*c)*R mod p + sul{{ .FIELD}}(&acMinBd, &ac, &bd) // = (a*c - b*d)*R*R + rdc{{ .FIELD}}(&dest.A, &acMinBd) // = (a*c - b*d)*R mod p +} + +// Set dest = 1/x +// +// Allowed to overlap dest with x. +// +// Returns dest to allow chaining operations. +func inv(dest, x *common.Fp2) { + var e1, e2 common.FpX2 + var f1, f2 common.Fp + + // We want to compute + // + // 1 1 (a - bi) (a - bi) + // -------- = -------- -------- = ----------- + // (a + bi) (a + bi) (a - bi) (a^2 + b^2) + // + // Letting c = 1/(a^2 + b^2), this is + // + // 1/(a+bi) = a*c - b*ci. + + mul{{ .FIELD}}(&e1, &x.A, &x.A) // = a*a*R*R + mul{{ .FIELD}}(&e2, &x.B, &x.B) // = b*b*R*R + adl{{ .FIELD}}(&e1, &e1, &e2) // = (a^2 + b^2)*R*R + rdc{{ .FIELD}}(&f1, &e1) // = (a^2 + b^2)*R mod p + // Now f1 = a^2 + b^2 + + mulP(&f2, &f1, &f1) + p34(&f2, &f2) + mulP(&f2, &f2, &f2) + mulP(&f2, &f2, &f1) + + mul{{ .FIELD}}(&e1, &x.A, &f2) + rdc{{ .FIELD}}(&dest.A, &e1) + + sub{{ .FIELD}}(&f1, &common.Fp{}, &x.B) + mul{{ .FIELD}}(&e1, &f1, &f2) + rdc{{ .FIELD}}(&dest.B, &e1) +} + +func sqr(dest, x *common.Fp2) { + var a2, aPlusB, aMinusB common.Fp + var a2MinB2, ab2 common.FpX2 + + a := &x.A + b := &x.B + + // (a + bi)*(a + bi) = (a^2 - b^2) + 2abi. + add{{ .FIELD}}(&a2, a, a) // = a*R + a*R = 2*a*R + add{{ .FIELD}}(&aPlusB, a, b) // = a*R + b*R = (a+b)*R + sub{{ .FIELD}}(&aMinusB, a, b) // = a*R - b*R = (a-b)*R + mul{{ .FIELD}}(&a2MinB2, &aPlusB, &aMinusB) // = (a+b)*(a-b)*R*R = (a^2 - b^2)*R*R + mul{{ .FIELD}}(&ab2, &a2, b) // = 2*a*b*R*R + rdc{{ .FIELD}}(&dest.A, &a2MinB2) // = (a^2 - b^2)*R mod p + rdc{{ .FIELD}}(&dest.B, &ab2) // = 2*a*b*R mod p +} + +// In case choice == 1, performs following swap in constant time: +// xPx <-> xQx +// xPz <-> xQz +// Otherwise returns xPx, xPz, xQx, xQz unchanged +func cswap(xPx, xPz, xQx, xQz *common.Fp2, choice uint8) { + cswap{{ .FIELD}}(&xPx.A, &xQx.A, choice) + cswap{{ .FIELD}}(&xPx.B, &xQx.B, choice) + cswap{{ .FIELD}}(&xPz.A, &xQz.A, choice) + cswap{{ .FIELD}}(&xPz.B, &xQz.B, choice) +} + +// Converts in.A and in.B to Montgomery domain and stores +// in 'out' +// out.A = in.A * R mod p +// out.B = in.B * R mod p +// Performs v = v*R^2*R^(-1) mod p, for both in.A and in.B +func ToMontgomery(out, in *common.Fp2) { + var aRR common.FpX2 + + // a*R*R + mul{{ .FIELD}}(&aRR, &in.A, &{{ .FIELD}}R2) + // a*R mod p + rdc{{ .FIELD}}(&out.A, &aRR) + mul{{ .FIELD}}(&aRR, &in.B, &{{ .FIELD}}R2) + rdc{{ .FIELD}}(&out.B, &aRR) +} + +// Converts in.A and in.B from Montgomery domain and stores +// in 'out' +// out.A = in.A mod p +// out.B = in.B mod p +// +// After returning from the call 'in' is not modified. +func FromMontgomery(out, in *common.Fp2) { + var aR common.FpX2 + + // convert from montgomery domain + copy(aR[:], in.A[:]) + rdc{{ .FIELD}}(&out.A, &aR) // = a mod p in [0, 2p) + mod{{ .FIELD}}(&out.A) // = a mod p in [0, p) + for i := range aR { + aR[i] = 0 + } + copy(aR[:], in.B[:]) + rdc{{ .FIELD}}(&out.B, &aR) + mod{{ .FIELD}}(&out.B) +} diff --git a/dh/sidh/internal/templates/fp2_test.gotemp b/dh/sidh/internal/templates/fp2_test.gotemp new file mode 100644 index 0000000..4b892a3 --- /dev/null +++ b/dh/sidh/internal/templates/fp2_test.gotemp @@ -0,0 +1,245 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by robots. + +package {{ .PACKAGE}} + +import ( + "math/rand" + "reflect" + "testing" + "testing/quick" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" +) + +type testParams struct { + Point common.ProjectivePoint + Cparam common.ProjectiveCurveParameters + ExtElem common.Fp2 +} + +// Returns true if lhs = rhs. Takes variable time. +func vartimeEqFp2(lhs, rhs *common.Fp2) bool { + a := *lhs + b := *rhs + + mod{{ .FIELD}}(&a.A) + mod{{ .FIELD}}(&a.B) + mod{{ .FIELD}}(&b.A) + mod{{ .FIELD}}(&b.B) + + eq := true + for i := 0; i < FpWords && eq; i++ { + eq = eq && (a.A[i] == b.A[i]) + eq = eq && (a.B[i] == b.B[i]) + } + return eq +} + +func (testParams) generateFp2(rand *rand.Rand) common.Fp2 { + // Generation strategy: low limbs taken from [0,2^64); high limb + // taken from smaller range + // + // Size hint is ignored since all elements are fixed size. + // + // Field elements taken in range [0,2p). Emulate this by capping + // the high limb by the top digit of 2*p-1: + // + // sage: (2*p-1).digits(2^64)[-1] + // + // This still allows generating values >= 2p, but hopefully that + // excess is OK (and if it's not, we'll find out, because it's for + // testing...) + highLimb := rand.Uint64() % {{ .FIELD}}x2[FpWords-1] + fpElementGen := func() (fp common.Fp) { + for i := 0; i < (FpWords - 1); i++ { + fp[i] = rand.Uint64() + } + fp[FpWords-1] = highLimb + return fp + } + return common.Fp2{A: fpElementGen(), B: fpElementGen()} +} + +func (c testParams) Generate(rand *rand.Rand, size int) reflect.Value { + return reflect.ValueOf( + testParams{ + common.ProjectivePoint{ + X: c.generateFp2(rand), + Z: c.generateFp2(rand), + }, + common.ProjectiveCurveParameters{ + A: c.generateFp2(rand), + C: c.generateFp2(rand), + }, + c.generateFp2(rand), + }) +} + +func TestOne(t *testing.T) { + var tmp common.Fp2 + + mul(&tmp, ¶ms.OneFp2, ¶ms.A.AffineP) + if !vartimeEqFp2(&tmp, ¶ms.A.AffineP) { + t.Error("Not equal 1") + } +} + +func TestFp2ToBytesRoundTrip(t *testing.T) { + roundTrips := func(x testParams) bool { + var xBytes = make([]byte, 2*params.Bytelen) + var xPrime common.Fp2 + + common.Fp2ToBytes(xBytes[:], &x.ExtElem, params.Bytelen) + common.BytesToFp2(&xPrime, xBytes[:], params.Bytelen) + return vartimeEqFp2(&xPrime, &x.ExtElem) + } + + if err := quick.Check(roundTrips, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2MulDistributesOverAdd(t *testing.T) { + mulDistributesOverAdd := func(x, y, z testParams) bool { + // Compute t1 = (x+y)*z + t1 := new(common.Fp2) + add(t1, &x.ExtElem, &y.ExtElem) + mul(t1, t1, &z.ExtElem) + + // Compute t2 = x*z + y*z + t2 := new(common.Fp2) + t3 := new(common.Fp2) + mul(t2, &x.ExtElem, &z.ExtElem) + mul(t3, &y.ExtElem, &z.ExtElem) + add(t2, t2, t3) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(mulDistributesOverAdd, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2MulIsAssociative(t *testing.T) { + isAssociative := func(x, y, z testParams) bool { + // Compute t1 = (x*y)*z + t1 := new(common.Fp2) + mul(t1, &x.ExtElem, &y.ExtElem) + mul(t1, t1, &z.ExtElem) + + // Compute t2 = (y*z)*x + t2 := new(common.Fp2) + mul(t2, &y.ExtElem, &z.ExtElem) + mul(t2, t2, &x.ExtElem) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(isAssociative, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2SquareMatchesMul(t *testing.T) { + sqrMatchesMul := func(x testParams) bool { + // Compute t1 = (x*x) + t1 := new(common.Fp2) + mul(t1, &x.ExtElem, &x.ExtElem) + + // Compute t2 = x^2 + t2 := new(common.Fp2) + sqr(t2, &x.ExtElem) + + return vartimeEqFp2(t1, t2) + } + + if err := quick.Check(sqrMatchesMul, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2Inv(t *testing.T) { + inverseIsCorrect := func(x testParams) bool { + z := new(common.Fp2) + inv(z, &x.ExtElem) + + // Now z = (1/x), so (z * x) * x == x + mul(z, z, &x.ExtElem) + mul(z, z, &x.ExtElem) + + return vartimeEqFp2(z, &x.ExtElem) + } + + // This is more expensive; run fewer tests + var quickCheckConfig = &quick.Config{MaxCount: (1 << 11)} + if err := quick.Check(inverseIsCorrect, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func TestFp2Batch3Inv(t *testing.T) { + batchInverseIsCorrect := func(x1, x2, x3 testParams) bool { + var x1Inv, x2Inv, x3Inv common.Fp2 + inv(&x1Inv, &x1.ExtElem) + inv(&x2Inv, &x2.ExtElem) + inv(&x3Inv, &x3.ExtElem) + + var y1, y2, y3 common.Fp2 + Fp2Batch3Inv(&x1.ExtElem, &x2.ExtElem, &x3.ExtElem, &y1, &y2, &y3) + + return (vartimeEqFp2(&x1Inv, &y1) && vartimeEqFp2(&x2Inv, &y2) && vartimeEqFp2(&x3Inv, &y3)) + } + + // This is more expensive; run fewer tests + var quickCheckConfig = &quick.Config{MaxCount: (1 << 8)} + if err := quick.Check(batchInverseIsCorrect, quickCheckConfig); err != nil { + t.Error(err) + } +} + +func BenchmarkFp2Mul(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + mul(w, z, z) + } +} + +func BenchmarkFp2Inv(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + inv(w, z) + } +} + +func BenchmarkFp2Square(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + sqr(w, z) + } +} + +func BenchmarkFp2Add(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + add(w, z, z) + } +} + +func BenchmarkFp2Sub(b *testing.B) { + z := &common.Fp2{A: bench_x, B: bench_y} + w := new(common.Fp2) + + for n := 0; n < b.N; n++ { + sub(w, z, z) + } +} diff --git a/dh/sidh/internal/templates/gen.go b/dh/sidh/internal/templates/gen.go new file mode 100644 index 0000000..bfb9974 --- /dev/null +++ b/dh/sidh/internal/templates/gen.go @@ -0,0 +1,106 @@ +// The following directive is necessary to make the package coherent: + +// +build ignore + +// This program generates contributors.go. It can be invoked by running +// go generate +package main + +import ( + "fmt" + "os" + "strings" + "text/template" +) + +var p34 = map[string]struct { + pow_strategy string + mul_strategy string + mul_initial int +}{ + "P434": { + pow_strategy: "[]uint8{3, 10, 7, 5, 6, 5, 3, 8, 4, 7, 5, 6, 4, 5, 9, 6, 3, 11, 5, 5, 2, 8, 4, 7, 7, 8, 5, 6, 4, 8, 5, 2, 10, 6, 5, 4, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1}", + mul_strategy: "[]uint8{2, 15, 9, 8, 14, 12, 2, 8, 5, 15, 8, 15, 6, 6, 3, 2, 0, 10, 9, 13, 1, 12, 3, 7, 1, 10, 8, 11, 2, 15, 14, 1, 11, 12, 14, 3, 11, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0}", + mul_initial: 8, + }, + "P503": { + pow_strategy: "[]uint8{12, 5, 5, 2, 7, 11, 3, 8, 4, 11, 4, 7, 5, 6, 3, 7, 5, 7, 2, 12, 5, 6, 4, 6, 8, 6, 4, 7, 5, 5, 8, 5, 8, 5, 5, 8, 9, 3, 6, 2, 10, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3}", + mul_strategy: "[]uint8{12, 11, 10, 0, 1, 8, 3, 7, 1, 8, 3, 6, 7, 14, 2, 14, 14, 9, 0, 13, 9, 15, 5, 12, 7, 13, 7, 15, 6, 7, 9, 0, 5, 7, 6, 8, 8, 3, 7, 0, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3}", + mul_initial: 0, + }, + "P751": { + pow_strategy: "[]uint8{5, 7, 6, 2, 10, 4, 6, 9, 8, 5, 9, 4, 7, 5, 5, 4, 8, 3, 9, 5, 5, 4, 10, 4, 6, 6, 6, 5, 8, 9, 3, 4, 9, 4, 5, 6, 6, 2, 9, 4, 5, 5, 5, 7, 7, 9, 4, 6, 4, 8, 5, 8, 6, 6, 2, 9, 7, 4, 8, 8, 8, 4, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2}", + mul_strategy: "[]uint8{15, 11, 10, 0, 15, 3, 3, 3, 4, 4, 9, 7, 11, 11, 5, 3, 12, 2, 10, 8, 5, 2, 8, 3, 5, 4, 11, 4, 0, 9, 2, 1, 12, 7, 5, 14, 15, 0, 14, 5, 6, 4, 5, 13, 6, 9, 7, 15, 1, 14, 11, 15, 12, 5, 0, 10, 9, 7, 7, 10, 14, 6, 11, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1}", + mul_initial: 13, + }, +} + +// P434 optimized implementation for +// ARM64 is not ported yet +var opt_arm = map[string]bool{ + "P434": false, + "P503": true, + "P751": true, +} + +// Generates an 'fileNameBase.go' from 'fileNameBase.gotemp' file +// for a given finite 'field'. Maps placeholders to 'values'. +func gen(field, fileNameBase string, values interface{}) { + // name of the output .go file + outFileName := fileNameBase + ".go" + out, err := os.Create(outFileName) + if err != nil { + panic("Cannot open file") + } + + // Template files are located in ../templates and have + // extension .gotemp + templateFile := "../templates/" + fileNameBase + ".gotemp" + t, err := template.ParseFiles(templateFile) + if err != nil { + panic(fmt.Sprintf("Cannot open template file %s", templateFile)) + } + + t.Execute(out, values) + err = out.Close() + if err != nil { + panic("Cant close generated file") + } +} + +func main() { + field := os.Args[1] + + s := struct { + FIELD string + PACKAGE string + P34_POW_STRATEGY string + P34_MUL_STRATEGY string + P34_INITIAL_MUL int + OPT_ARM bool + }{ + FIELD: field, + PACKAGE: strings.ToLower(field), + P34_POW_STRATEGY: p34[field].pow_strategy, + P34_MUL_STRATEGY: p34[field].mul_strategy, + P34_INITIAL_MUL: p34[field].mul_initial, + OPT_ARM: opt_arm[field], + } + + targets := map[string]interface{}{ + "arith_decl": s, + "arith_generic": s, + "curve": s, + "fp2": s, + "core": s, + + // tests + "arith_test": s, + "fp2_test": s, + "curve_test": s, + } + + for v, s := range targets { + gen(field, v, s) + } +} diff --git a/dh/sidh/p503/arith_generic.go b/dh/sidh/p503/arith_generic.go deleted file mode 100644 index 312dcb4..0000000 --- a/dh/sidh/p503/arith_generic.go +++ /dev/null @@ -1,197 +0,0 @@ -// +build noasm !amd64,!arm64 - -package p503 - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/arith" - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" -) - -// Compute z = x + y (mod p). -func fp503AddReduced(z, x, y *FpElement) { - var carry uint64 - - // z=x+y % p503 - for i := 0; i < NumWords; i++ { - z[i], carry = Addc64(carry, x[i], y[i]) - } - - // z = z - p503x2 - carry = 0 - for i := 0; i < NumWords; i++ { - z[i], carry = Subc64(carry, z[i], p503x2[i]) - } - - // if z<0 add p503x2 back - mask := uint64(0 - carry) - carry = 0 - for i := 0; i < NumWords; i++ { - z[i], carry = Addc64(carry, z[i], p503x2[i]&mask) - } -} - -// Compute z = x - y (mod p). -func fp503SubReduced(z, x, y *FpElement) { - var borrow uint64 - - // z = z - p503x2 - for i := 0; i < NumWords; i++ { - z[i], borrow = Subc64(borrow, x[i], y[i]) - } - - // if z<0 add p503x2 back - mask := uint64(0 - borrow) - borrow = 0 - for i := 0; i < NumWords; i++ { - z[i], borrow = Addc64(borrow, z[i], p503x2[i]&mask) - } -} - -// Conditionally swaps bits in x and y in constant time. -// mask indicates bits to be swapped (set bits are swapped) -// For details see "Hackers Delight, 2.20" -// -// Implementation doesn't actually depend on a prime field. -func fp503ConditionalSwap(x, y *FpElement, mask uint8) { - var tmp, mask64 uint64 - - mask64 = 0 - uint64(mask) - for i := 0; i < NumWords; i++ { - tmp = mask64 & (x[i] ^ y[i]) - x[i] = tmp ^ x[i] - y[i] = tmp ^ y[i] - } -} - -// Perform Montgomery reduction: set z = x R^{-1} (mod 2*p) -// with R=2^512. Destroys the input value. -func fp503MontgomeryReduce(z *FpElement, x *FpElementX2) { - var carry, t, u, v uint64 - var uv Uint128 - var count int - - count = 3 // number of 0 digits in the least significat part of p503 + 1 - - for i := 0; i < NumWords; i++ { - for j := 0; j < i; j++ { - if j < (i - count + 1) { - uv = Mul64(z[j], p503p1[i-j]) - v, carry = Addc64(0, uv.L, v) - u, carry = Addc64(carry, uv.H, u) - t += carry - } - } - v, carry = Addc64(0, v, x[i]) - u, carry = Addc64(carry, u, 0) - t += carry - - z[i] = v - v = u - u = t - t = 0 - } - - for i := NumWords; i < 2*NumWords-1; i++ { - if count > 0 { - count-- - } - for j := i - NumWords + 1; j < NumWords; j++ { - if j < (NumWords - count) { - uv = Mul64(z[j], p503p1[i-j]) - v, carry = Addc64(0, uv.L, v) - u, carry = Addc64(carry, uv.H, u) - t += carry - } - } - v, carry = Addc64(0, v, x[i]) - u, carry = Addc64(carry, u, 0) - - t += carry - z[i-NumWords] = v - v = u - u = t - t = 0 - } - v, carry = Addc64(0, v, x[2*NumWords-1]) - z[NumWords-1] = v -} - -// Compute z = x * y. -func fp503Mul(z *FpElementX2, x, y *FpElement) { - var u, v, t uint64 - var carry uint64 - var uv Uint128 - - for i := uint64(0); i < NumWords; i++ { - for j := uint64(0); j <= i; j++ { - uv = Mul64(x[j], y[i-j]) - v, carry = Addc64(0, uv.L, v) - u, carry = Addc64(carry, uv.H, u) - t += carry - } - z[i] = v - v = u - u = t - t = 0 - } - - for i := NumWords; i < (2*NumWords)-1; i++ { - for j := i - NumWords + 1; j < NumWords; j++ { - uv = Mul64(x[j], y[i-j]) - v, carry = Addc64(0, uv.L, v) - u, carry = Addc64(carry, uv.H, u) - t += carry - } - z[i] = v - v = u - u = t - t = 0 - } - z[2*NumWords-1] = v -} - -// Compute z = x + y, without reducing mod p. -func fp503AddLazy(z, x, y *FpElement) { - var carry uint64 - for i := 0; i < NumWords; i++ { - z[i], carry = Addc64(carry, x[i], y[i]) - } -} - -// Compute z = x + y, without reducing mod p. -func fp503X2AddLazy(z, x, y *FpElementX2) { - var carry uint64 - for i := 0; i < 2*NumWords; i++ { - z[i], carry = Addc64(carry, x[i], y[i]) - } -} - -// Reduce a field element in [0, 2*p) to one in [0,p). -func fp503StrongReduce(x *FpElement) { - var borrow, mask uint64 - for i := 0; i < NumWords; i++ { - x[i], borrow = Subc64(borrow, x[i], p503[i]) - } - - // Sets all bits if borrow = 1 - mask = 0 - borrow - borrow = 0 - for i := 0; i < NumWords; i++ { - x[i], borrow = Addc64(borrow, x[i], p503[i]&mask) - } -} - -// Compute z = x - y, without reducing mod p. -func fp503X2SubLazy(z, x, y *FpElementX2) { - var borrow, mask uint64 - for i := 0; i < 2*NumWords; i++ { - z[i], borrow = Subc64(borrow, x[i], y[i]) - } - - // Sets all bits if borrow = 1 - mask = 0 - borrow - borrow = 0 - for i := NumWords; i < 2*NumWords; i++ { - z[i], borrow = Addc64(borrow, z[i], p503[i-NumWords]&mask) - } -} diff --git a/dh/sidh/p503/arith_test.go b/dh/sidh/p503/arith_test.go deleted file mode 100644 index 8f7dd77..0000000 --- a/dh/sidh/p503/arith_test.go +++ /dev/null @@ -1,341 +0,0 @@ -package p503 - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - "math/big" - "testing" - "testing/quick" -) - -//------------------------------------------------------------------------------ -// Extended Field -//------------------------------------------------------------------------------ - -func TestOneFp2ToBytes(t *testing.T) { - var x = P503OneFp2 - var xBytes [2 * P503_Bytelen]byte - - kCurveOps.Fp2ToBytes(xBytes[:], &x) - if xBytes[0] != 1 { - t.Error("Expected 1, got", xBytes[0]) - } - for i := 1; i < 2*P503_Bytelen; i++ { - if xBytes[i] != 0 { - t.Error("Expected 0, got", xBytes[0]) - } - } -} - -func TestFp2ElementToBytesRoundTrip(t *testing.T) { - roundTrips := func(x GeneratedTestParams) bool { - var xBytes [2 * P503_Bytelen]byte - var xPrime Fp2Element - - kCurveOps.Fp2ToBytes(xBytes[:], &x.ExtElem) - kCurveOps.Fp2FromBytes(&xPrime, xBytes[:]) - return VartimeEqFp2(&xPrime, &x.ExtElem) - } - - if err := quick.Check(roundTrips, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestFp2ElementMulDistributesOverAdd(t *testing.T) { - mulDistributesOverAdd := func(x, y, z GeneratedTestParams) bool { - // Compute t1 = (x+y)*z - t1 := new(Fp2Element) - kFieldOps.Add(t1, &x.ExtElem, &y.ExtElem) - kFieldOps.Mul(t1, t1, &z.ExtElem) - - // Compute t2 = x*z + y*z - t2 := new(Fp2Element) - t3 := new(Fp2Element) - kFieldOps.Mul(t2, &x.ExtElem, &z.ExtElem) - kFieldOps.Mul(t3, &y.ExtElem, &z.ExtElem) - kFieldOps.Add(t2, t2, t3) - - return VartimeEqFp2(t1, t2) - } - - if err := quick.Check(mulDistributesOverAdd, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestFp2ElementMulIsAssociative(t *testing.T) { - isAssociative := func(x, y, z GeneratedTestParams) bool { - // Compute t1 = (x*y)*z - t1 := new(Fp2Element) - kFieldOps.Mul(t1, &x.ExtElem, &y.ExtElem) - kFieldOps.Mul(t1, t1, &z.ExtElem) - - // Compute t2 = (y*z)*x - t2 := new(Fp2Element) - kFieldOps.Mul(t2, &y.ExtElem, &z.ExtElem) - kFieldOps.Mul(t2, t2, &x.ExtElem) - - return VartimeEqFp2(t1, t2) - } - - if err := quick.Check(isAssociative, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestFp2ElementSquareMatchesMul(t *testing.T) { - sqrMatchesMul := func(x GeneratedTestParams) bool { - // Compute t1 = (x*x) - t1 := new(Fp2Element) - kFieldOps.Mul(t1, &x.ExtElem, &x.ExtElem) - - // Compute t2 = x^2 - t2 := new(Fp2Element) - kFieldOps.Square(t2, &x.ExtElem) - - return VartimeEqFp2(t1, t2) - } - - if err := quick.Check(sqrMatchesMul, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestFp2ElementInv(t *testing.T) { - inverseIsCorrect := func(x GeneratedTestParams) bool { - z := new(Fp2Element) - kFieldOps.Inv(z, &x.ExtElem) - - // Now z = (1/x), so (z * x) * x == x - kFieldOps.Mul(z, z, &x.ExtElem) - kFieldOps.Mul(z, z, &x.ExtElem) - - return VartimeEqFp2(z, &x.ExtElem) - } - - // This is more expensive; run fewer tests - var quickCheckConfig = &quick.Config{MaxCount: (1 << (8 + quickCheckScaleFactor))} - if err := quick.Check(inverseIsCorrect, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestFp2ElementBatch3Inv(t *testing.T) { - batchInverseIsCorrect := func(x1, x2, x3 GeneratedTestParams) bool { - var x1Inv, x2Inv, x3Inv Fp2Element - kFieldOps.Inv(&x1Inv, &x1.ExtElem) - kFieldOps.Inv(&x2Inv, &x2.ExtElem) - kFieldOps.Inv(&x3Inv, &x3.ExtElem) - - var y1, y2, y3 Fp2Element - kCurveOps.Fp2Batch3Inv(&x1.ExtElem, &x2.ExtElem, &x3.ExtElem, &y1, &y2, &y3) - - return (VartimeEqFp2(&x1Inv, &y1) && VartimeEqFp2(&x2Inv, &y2) && VartimeEqFp2(&x3Inv, &y3)) - } - - // This is more expensive; run fewer tests - var quickCheckConfig = &quick.Config{MaxCount: (1 << (5 + quickCheckScaleFactor))} - if err := quick.Check(batchInverseIsCorrect, quickCheckConfig); err != nil { - t.Error(err) - } -} - -//------------------------------------------------------------------------------ -// Prime Field -//------------------------------------------------------------------------------ - -func TestPrimeFieldElementMulVersusBigInt(t *testing.T) { - mulMatchesBigInt := func(x, y primeFieldElement) bool { - z := new(primeFieldElement) - z.Mul(&x, &y) - check := new(big.Int) - check.Mul(toBigInt(&x.A), toBigInt(&y.A)) - check.Mod(check, p503BigIntPrime) - return check.Cmp(toBigInt(&z.A)) == 0 - } - - if err := quick.Check(mulMatchesBigInt, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestPrimeFieldElementP34VersusBigInt(t *testing.T) { - var p34, _ = new(big.Int).SetString("3293960789226779345209813229049836260623046691894590999611415869258960983005190308379728727886506087902151787597521914245745576582754898490288559357951", 10) - p34MatchesBigInt := func(x primeFieldElement) bool { - z := new(primeFieldElement) - z.P34(&x) - - check := toBigInt(&x.A) - check.Exp(check, p34, p503BigIntPrime) - - return check.Cmp(toBigInt(&z.A)) == 0 - } - - // This is more expensive; run fewer tests - var quickCheckConfig = &quick.Config{MaxCount: (1 << (8 + quickCheckScaleFactor))} - if err := quick.Check(p34MatchesBigInt, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestPrimeFieldElementToBigInt(t *testing.T) { - // Chosen so that p < xR < 2p - x := primeFieldElement{A: FpElement{ - 1, 1, 1, 1, 1, 1, 1, 36028797018963968, - }, - } - // Computed using Sage: - // sage: p = 2^e2 * 3^e3 - 1 - // sage: R = 2^512 - // sage: from_radix_64 = lambda xs: sum((xi * (2**64)**i for i,xi in enumerate(xs))) - // sage: xR = from_radix_64([1]*7 + [2^55]) - // sage: assert(p < xR) - // sage: assert(xR < 2*p) - // sage: (xR / R) % p - xBig, _ := new(big.Int).SetString("9018685569593152305590037326062904046918870374552508285127709347526265324701162612011653377441752634975109935373869185819144129719824212073345315986301", 10) - if xBig.Cmp(toBigInt(&x.A)) != 0 { - t.Error("Expected", xBig, "found", toBigInt(&x.A)) - } -} - -func TestFpElementConditionalSwap(t *testing.T) { - var one = FpElement{1, 1, 1, 1, 1, 1, 1, 1} - var two = FpElement{2, 2, 2, 2, 2, 2, 2, 2} - - var x = one - var y = two - - fp503ConditionalSwap(&x, &y, 0) - - if !(x == one && y == two) { - t.Error("Found", x, "expected", one) - } - - fp503ConditionalSwap(&x, &y, 1) - - if !(x == two && y == one) { - t.Error("Found", x, "expected", two) - } -} - -func BenchmarkFp2ElementMul(b *testing.B) { - z := &Fp2Element{A: bench_x, B: bench_y} - w := new(Fp2Element) - - for n := 0; n < b.N; n++ { - kFieldOps.Mul(w, z, z) - } -} - -func BenchmarkFp2ElementInv(b *testing.B) { - z := &Fp2Element{A: bench_x, B: bench_y} - w := new(Fp2Element) - - for n := 0; n < b.N; n++ { - kFieldOps.Inv(w, z) - } -} - -func BenchmarkFp2ElementSquare(b *testing.B) { - z := &Fp2Element{A: bench_x, B: bench_y} - w := new(Fp2Element) - - for n := 0; n < b.N; n++ { - kFieldOps.Square(w, z) - } -} - -func BenchmarkFp2ElementAdd(b *testing.B) { - z := &Fp2Element{A: bench_x, B: bench_y} - w := new(Fp2Element) - - for n := 0; n < b.N; n++ { - kFieldOps.Add(w, z, z) - } -} - -func BenchmarkFp2ElementSub(b *testing.B) { - z := &Fp2Element{A: bench_x, B: bench_y} - w := new(Fp2Element) - - for n := 0; n < b.N; n++ { - kFieldOps.Sub(w, z, z) - } -} - -func BenchmarkPrimeFieldElementMul(b *testing.B) { - z := &primeFieldElement{A: bench_x} - w := new(primeFieldElement) - - for n := 0; n < b.N; n++ { - w.Mul(z, z) - } -} - -// --- field operation functions - -func BenchmarkFp503Multiply(b *testing.B) { - for n := 0; n < b.N; n++ { - fp503Mul(&benchmarkFpElementX2, &bench_x, &bench_y) - } -} - -func BenchmarkFp503MontgomeryReduce(b *testing.B) { - z := bench_z - - // This benchmark actually computes garbage, because - // fp503MontgomeryReduce mangles its input, but since it's - // constant-time that shouldn't matter for the benchmarks. - for n := 0; n < b.N; n++ { - fp503MontgomeryReduce(&benchmarkFpElement, &z) - } -} - -func BenchmarkFp503AddReduced(b *testing.B) { - for n := 0; n < b.N; n++ { - fp503AddReduced(&benchmarkFpElement, &bench_x, &bench_y) - } -} - -func BenchmarkFp503SubReduced(b *testing.B) { - for n := 0; n < b.N; n++ { - fp503SubReduced(&benchmarkFpElement, &bench_x, &bench_y) - } -} - -func BenchmarkFp503ConditionalSwap(b *testing.B) { - x, y := bench_x, bench_y - for n := 0; n < b.N; n++ { - fp503ConditionalSwap(&x, &y, 1) - fp503ConditionalSwap(&x, &y, 0) - } -} - -func BenchmarkFp503StrongReduce(b *testing.B) { - x := bench_x - for n := 0; n < b.N; n++ { - fp503StrongReduce(&x) - } -} - -func BenchmarkFp503AddLazy(b *testing.B) { - var z FpElement - x, y := bench_x, bench_y - for n := 0; n < b.N; n++ { - fp503AddLazy(&z, &x, &y) - } -} - -func BenchmarkFp503X2AddLazy(b *testing.B) { - x, y, z := bench_z, bench_z, bench_z - for n := 0; n < b.N; n++ { - fp503X2AddLazy(&x, &y, &z) - } -} - -func BenchmarkFp503X2SubLazy(b *testing.B) { - x, y, z := bench_z, bench_z, bench_z - for n := 0; n < b.N; n++ { - fp503X2SubLazy(&x, &y, &z) - } -} diff --git a/dh/sidh/p503/consts.go b/dh/sidh/p503/consts.go deleted file mode 100644 index 45a0708..0000000 --- a/dh/sidh/p503/consts.go +++ /dev/null @@ -1,178 +0,0 @@ -package p503 - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - cpu "github.com/henrydcase/nobs/utils" -) - -const ( - // SIDH public key byte size - P503_PublicKeySize = 378 - // SIDH shared secret byte size. - P503_SharedSecretSize = 126 - // Max size of secret key for 2-torsion group, corresponds to 2^e2 - 1 - P503_SecretBitLenA = 250 - // Size of secret key for 3-torsion group, corresponds to log_2(3^e3) - 1 - P503_SecretBitLenB = 252 - // Size of a compuatation strategy for 2-torsion group - strategySizeA = 124 - // Size of a compuatation strategy for 3-torsion group - strategySizeB = 158 - // ceil(503+7/8) - P503_Bytelen = 63 - // Number of limbs for a field element - NumWords = 8 -) - -// CPU Capabilities. Those flags are referred by assembly code. According to -// https://github.com/golang/go/issues/28230, variables referred from the -// assembly must be in the same package. -// We declare them variables not constants in order to facilitate testing. -var ( - // Signals support for MULX which is in BMI2 - HasBMI2 = cpu.X86.HasBMI2 - // Signals support for ADX and BMI2 - HasADXandBMI2 = cpu.X86.HasBMI2 && cpu.X86.HasADX -) - -// The x-coordinate of PA -var P503_affine_PA = Fp2Element{ - A: FpElement{ - 0xE7EF4AA786D855AF, 0xED5758F03EB34D3B, 0x09AE172535A86AA9, 0x237B9CC07D622723, - 0xE3A284CBA4E7932D, 0x27481D9176C5E63F, 0x6A323FF55C6E71BF, 0x002ECC31A6FB8773, - }, - B: FpElement{ - 0x64D02E4E90A620B8, 0xDAB8128537D4B9F1, 0x4BADF77B8A228F98, 0x0F5DBDF9D1FB7D1B, - 0xBEC4DB288E1A0DCC, 0xE76A8665E80675DB, 0x6D6F252E12929463, 0x003188BD1463FACC, - }, -} - -// The x-coordinate of QA -var P503_affine_QA = Fp2Element{ - A: FpElement{ - 0xB79D41025DE85D56, 0x0B867DA9DF169686, 0x740E5368021C827D, 0x20615D72157BF25C, - 0xFF1590013C9B9F5B, 0xC884DCADE8C16CEA, 0xEBD05E53BF724E01, 0x0032FEF8FDA5748C, - }, - B: FpElement{ - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - }, -} - -// The x-coordinate of RA = PA-QA -var P503_affine_RA = Fp2Element{ - A: FpElement{ - 0x12E2E849AA0A8006, 0x41CF47008635A1E8, 0x9CD720A70798AED7, 0x42A820B42FCF04CF, - 0x7BF9BAD32AAE88B1, 0xF619127A54090BBE, 0x1CB10D8F56408EAA, 0x001D6B54C3C0EDEB, - }, - B: FpElement{ - 0x34DB54931CBAAC36, 0x420A18CB8DD5F0C4, 0x32008C1A48C0F44D, 0x3B3BA772B1CFD44D, - 0xA74B058FDAF13515, 0x095FC9CA7EEC17B4, 0x448E829D28F120F8, 0x00261EC3ED16A489, - }, -} - -// The x-coordinate of PB -var P503_affine_PB = Fp2Element{ - A: FpElement{ - 0x7EDE37F4FA0BC727, 0xF7F8EC5C8598941C, 0xD15519B516B5F5C8, 0xF6D5AC9B87A36282, - 0x7B19F105B30E952E, 0x13BD8B2025B4EBEE, 0x7B96D27F4EC579A2, 0x00140850CAB7E5DE, - }, - B: FpElement{ - 0x7764909DAE7B7B2D, 0x578ABB16284911AB, 0x76E2BFD146A6BF4D, 0x4824044B23AA02F0, - 0x1105048912A321F3, 0xB8A2E482CF0F10C1, 0x42FF7D0BE2152085, 0x0018E599C5223352, - }, -} - -// The x-coordinate of QB -var P503_affine_QB = Fp2Element{ - A: FpElement{ - 0x4256C520FB388820, 0x744FD7C3BAAF0A13, 0x4B6A2DDDB12CBCB8, 0xE46826E27F427DF8, - 0xFE4A663CD505A61B, 0xD6B3A1BAF025C695, 0x7C3BB62B8FCC00BD, 0x003AFDDE4A35746C, - }, - B: FpElement{ - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - }, -} - -// The x-coordinate of RB = PB - QB -var P503_affine_RB = Fp2Element{ - A: FpElement{ - 0x75601CD1E6C0DFCB, 0x1A9007239B58F93E, 0xC1F1BE80C62107AC, 0x7F513B898F29FF08, - 0xEA0BEDFF43E1F7B2, 0x2C6D94018CBAE6D0, 0x3A430D31BCD84672, 0x000D26892ECCFE83, - }, - B: FpElement{ - 0x1119D62AEA3007A1, 0xE3702AA4E04BAE1B, 0x9AB96F7D59F990E7, 0xF58440E8B43319C0, - 0xAF8134BEE1489775, 0xE7F7774E905192AA, 0xF54AE09308E98039, 0x001EF7A041A86112, - }, -} - -// 2-torsion group computation strategy -var P503_AliceIsogenyStrategy = [strategySizeA]uint32{ - 0x3D, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, - 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, - 0x01, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, - 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x1D, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, - 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x0D, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x05, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01} - -// 3-torsion group computation strategy -var P503_BobIsogenyStrategy = [strategySizeB]uint32{ - 0x47, 0x26, 0x15, 0x0D, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x05, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x09, - 0x05, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x11, 0x09, 0x05, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, - 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x21, 0x11, 0x09, 0x05, 0x03, 0x02, 0x01, 0x01, - 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, - 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x10, 0x08, - 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, - 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01} - -// Used internally by this package -// ------------------------------- - -var p503 = FpElement{ - 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xABFFFFFFFFFFFFFF, - 0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E, -} - -// 2*503 -var p503x2 = FpElement{ - 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x57FFFFFFFFFFFFFF, - 0x2610B7B44423CF41, 0x3737ED90F6FCFB5E, 0xC08B8D7BB4EF49A0, 0x0080CDEA83023C3C, -} - -// p503 + 1 -var p503p1 = FpElement{ - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xAC00000000000000, - 0x13085BDA2211E7A0, 0x1B9BF6C87B7E7DAF, 0x6045C6BDDA77A4D0, 0x004066F541811E1E, -} - -// R^2=(2^512)^2 mod p -var p503R2 = FpElement{ - 0x5289A0CF641D011F, 0x9B88257189FED2B9, 0xA3B365D58DC8F17A, 0x5BC57AB6EFF168EC, - 0x9E51998BD84D4423, 0xBF8999CBAC3B5695, 0x46E9127BCE14CDB6, 0x003F6CFCE8B81771, -} - -// p503 + 1 left-shifted by 8, assuming little endianness -var p503p1s8 = FpElement{ - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x085BDA2211E7A0AC, 0x9BF6C87B7E7DAF13, 0x45C6BDDA77A4D01B, 0x4066F541811E1E60, -} - -// 1*R mod p -var P503OneFp2 = Fp2Element{ - A: FpElement{ - 0x00000000000003F9, 0x0000000000000000, 0x0000000000000000, 0xB400000000000000, - 0x63CB1A6EA6DED2B4, 0x51689D8D667EB37D, 0x8ACD77C71AB24142, 0x0026FBAEC60F5953}, -} - -// 1/2 * R mod p -var P503HalfFp2 = Fp2Element{ - A: FpElement{ - 0x00000000000001FC, 0x0000000000000000, 0x0000000000000000, 0xB000000000000000, - 0x3B69BB2464785D2A, 0x36824A2AF0FE9896, 0xF5899F427A94F309, 0x0033B15203C83BB8}, -} diff --git a/dh/sidh/p503/curve_test.go b/dh/sidh/p503/curve_test.go deleted file mode 100644 index 48827fa..0000000 --- a/dh/sidh/p503/curve_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package p503 - -import ( - "bytes" - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - "testing" - "testing/quick" -) - -func TestOne(t *testing.T) { - var tmp Fp2Element - - kFieldOps.Mul(&tmp, &P503OneFp2, &affine_xP) - if !VartimeEqFp2(&tmp, &affine_xP) { - t.Error("Not equal 1") - } -} - -// This test is here only to ensure that ScalarMult helper works correctly -func TestScalarMultVersusSage(t *testing.T) { - var xP ProjectivePoint - - xP = ProjectivePoint{X: affine_xP, Z: P503OneFp2} - xP = ScalarMult(&curve, &xP, mScalarBytes[:]) // = x([m]P) - affine_xQ := xP.ToAffine(kCurveOps) - if !VartimeEqFp2(&affine_xaP, affine_xQ) { - t.Error("\nExpected\n", affine_xaP, "\nfound\n", affine_xQ) - } -} - -func Test_jInvariant(t *testing.T) { - var curve = ProjectiveCurveParameters{A: curve_A, C: curve_C} - var jbufRes [P503_SharedSecretSize]byte - var jbufExp [P503_SharedSecretSize]byte - // Computed using Sage - // j = 3674553797500778604587777859668542828244523188705960771798425843588160903687122861541242595678107095655647237100722594066610650373491179241544334443939077738732728884873568393760629500307797547379838602108296735640313894560419*i + 3127495302417548295242630557836520229396092255080675419212556702820583041296798857582303163183558315662015469648040494128968509467224910895884358424271180055990446576645240058960358037224785786494172548090318531038910933793845 - var known_j = Fp2Element{ - A: FpElement{0x2c441d03b72e27c, 0xf2c6748151dbf84, 0x3a774f6191070e, 0xa7c6212c9c800ba6, 0x23921b5cf09abc27, 0x9e1baefbb3cd4265, 0x8cd6a289f12e10dc, 0x3fa364128cf87e}, - B: FpElement{0xe7497ac2bf6b0596, 0x629ee01ad23bd039, 0x95ee11587a119fa7, 0x572fb28a24772269, 0x3c00410b6c71567e, 0xe681e83a345f8a34, 0x65d21b1d96bd2d52, 0x7889a47e58901}, - } - kCurveOps.Jinvariant(&curve, jbufRes[:]) - kCurveOps.Fp2ToBytes(jbufExp[:], &known_j) - - if !bytes.Equal(jbufRes[:], jbufExp[:]) { - t.Error("Computed incorrect j-invariant: found\n", jbufRes, "\nexpected\n", jbufExp) - } -} - -func TestProjectivePointVartimeEq(t *testing.T) { - var xP ProjectivePoint - - xP = ProjectivePoint{X: affine_xP, Z: P503OneFp2} - xQ := xP - // Scale xQ, which results in the same projective point - kFieldOps.Mul(&xQ.X, &xQ.X, &curve_A) - kFieldOps.Mul(&xQ.Z, &xQ.Z, &curve_A) - if !VartimeEqProjFp2(&xP, &xQ) { - t.Error("Expected the scaled point to be equal to the original") - } -} - -func TestPointDoubleVersusSage(t *testing.T) { - var curve = ProjectiveCurveParameters{A: curve_A, C: curve_C} - var params = kCurveOps.CalcCurveParamsEquiv4(&curve) - var xP ProjectivePoint - - xP = ProjectivePoint{X: affine_xP, Z: P503OneFp2} - kCurveOps.Pow2k(&xP, ¶ms, 1) - affine_xQ := xP.ToAffine(kCurveOps) - if !VartimeEqFp2(affine_xQ, &affine_xP2) { - t.Error("\nExpected\n", affine_xP2, "\nfound\n", affine_xQ) - } -} - -func TestPointMul4VersusSage(t *testing.T) { - var params = kCurveOps.CalcCurveParamsEquiv4(&curve) - var xP ProjectivePoint - - xP = ProjectivePoint{X: affine_xP, Z: P503OneFp2} - kCurveOps.Pow2k(&xP, ¶ms, 2) - affine_xQ := xP.ToAffine(kCurveOps) - if !VartimeEqFp2(affine_xQ, &affine_xP4) { - t.Error("\nExpected\n", affine_xP4, "\nfound\n", affine_xQ) - } -} - -func TestPointMul9VersusSage(t *testing.T) { - var params = kCurveOps.CalcCurveParamsEquiv3(&curve) - var xP ProjectivePoint - - xP = ProjectivePoint{X: affine_xP, Z: P503OneFp2} - kCurveOps.Pow3k(&xP, ¶ms, 2) - affine_xQ := xP.ToAffine(kCurveOps) - if !VartimeEqFp2(affine_xQ, &affine_xP9) { - t.Error("\nExpected\n", affine_xP9, "\nfound\n", affine_xQ) - } -} - -func TestPointPow2kVersusScalarMult(t *testing.T) { - var xP, xQ, xR ProjectivePoint - var params = kCurveOps.CalcCurveParamsEquiv4(&curve) - - xP = ProjectivePoint{X: affine_xP, Z: P503OneFp2} - xQ = xP - kCurveOps.Pow2k(&xQ, ¶ms, 5) - xR = ScalarMult(&curve, &xP, []byte{32}) - affine_xQ := xQ.ToAffine(kCurveOps) // = x([32]P) - affine_xR := xR.ToAffine(kCurveOps) // = x([32]P) - - if !VartimeEqFp2(affine_xQ, affine_xR) { - t.Error("\nExpected\n", affine_xQ, "\nfound\n", affine_xR) - } -} - -func TestPointTripleVersusAddDouble(t *testing.T) { - tripleEqualsAddDouble := func(params GeneratedTestParams) bool { - var P2, P3, P2plusP ProjectivePoint - - eqivParams4 := kCurveOps.CalcCurveParamsEquiv4(¶ms.Cparam) - eqivParams3 := kCurveOps.CalcCurveParamsEquiv3(¶ms.Cparam) - P2 = params.Point - P3 = params.Point - kCurveOps.Pow2k(&P2, &eqivParams4, 1) // = x([2]P) - kCurveOps.Pow3k(&P3, &eqivParams3, 1) // = x([3]P) - P2plusP = AddProjFp2(&P2, ¶ms.Point, ¶ms.Point) // = x([2]P + P) - return VartimeEqProjFp2(&P3, &P2plusP) - } - - if err := quick.Check(tripleEqualsAddDouble, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func BenchmarkThreePointLadder255BitScalar(b *testing.B) { - var mScalarBytes = [...]uint8{203, 155, 185, 191, 131, 228, 50, 178, 207, 191, 61, 141, 174, 173, 207, 243, 159, 243, 46, 163, 19, 102, 69, 92, 36, 225, 0, 37, 114, 19, 191, 0} - for n := 0; n < b.N; n++ { - kCurveOps.ScalarMul3Pt(&curve, &threePointLadderInputs[0], &threePointLadderInputs[1], &threePointLadderInputs[2], 255, mScalarBytes[:]) - } -} diff --git a/dh/sidh/p503/field_ops.go b/dh/sidh/p503/field_ops.go deleted file mode 100644 index f0dd684..0000000 --- a/dh/sidh/p503/field_ops.go +++ /dev/null @@ -1,249 +0,0 @@ -package p503 - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" -) - -type fp503Ops struct{} - -func FieldOperations() FieldOps { - return &fp503Ops{} -} - -func (fp503Ops) Add(dest, lhs, rhs *Fp2Element) { - fp503AddReduced(&dest.A, &lhs.A, &rhs.A) - fp503AddReduced(&dest.B, &lhs.B, &rhs.B) -} - -func (fp503Ops) Sub(dest, lhs, rhs *Fp2Element) { - fp503SubReduced(&dest.A, &lhs.A, &rhs.A) - fp503SubReduced(&dest.B, &lhs.B, &rhs.B) -} - -func (fp503Ops) Mul(dest, lhs, rhs *Fp2Element) { - // Let (a,b,c,d) = (lhs.a,lhs.b,rhs.a,rhs.b). - a := &lhs.A - b := &lhs.B - c := &rhs.A - d := &rhs.B - - // We want to compute - // - // (a + bi)*(c + di) = (a*c - b*d) + (a*d + b*c)i - // - // Use Karatsuba's trick: note that - // - // (b - a)*(c - d) = (b*c + a*d) - a*c - b*d - // - // so (a*d + b*c) = (b-a)*(c-d) + a*c + b*d. - - var ac, bd FpElementX2 - fp503Mul(&ac, a, c) // = a*c*R*R - fp503Mul(&bd, b, d) // = b*d*R*R - - var b_minus_a, c_minus_d FpElement - fp503SubReduced(&b_minus_a, b, a) // = (b-a)*R - fp503SubReduced(&c_minus_d, c, d) // = (c-d)*R - - var ad_plus_bc FpElementX2 - fp503Mul(&ad_plus_bc, &b_minus_a, &c_minus_d) // = (b-a)*(c-d)*R*R - fp503X2AddLazy(&ad_plus_bc, &ad_plus_bc, &ac) // = ((b-a)*(c-d) + a*c)*R*R - fp503X2AddLazy(&ad_plus_bc, &ad_plus_bc, &bd) // = ((b-a)*(c-d) + a*c + b*d)*R*R - - fp503MontgomeryReduce(&dest.B, &ad_plus_bc) // = (a*d + b*c)*R mod p - - var ac_minus_bd FpElementX2 - fp503X2SubLazy(&ac_minus_bd, &ac, &bd) // = (a*c - b*d)*R*R - fp503MontgomeryReduce(&dest.A, &ac_minus_bd) // = (a*c - b*d)*R mod p -} - -// Set dest = 1/x -// -// Allowed to overlap dest with x. -// -// Returns dest to allow chaining operations. -func (fp503Ops) Inv(dest, x *Fp2Element) { - a := &x.A - b := &x.B - - // We want to compute - // - // 1 1 (a - bi) (a - bi) - // -------- = -------- -------- = ----------- - // (a + bi) (a + bi) (a - bi) (a^2 + b^2) - // - // Letting c = 1/(a^2 + b^2), this is - // - // 1/(a+bi) = a*c - b*ci. - - var asq_plus_bsq primeFieldElement - var asq, bsq FpElementX2 - fp503Mul(&asq, a, a) // = a*a*R*R - fp503Mul(&bsq, b, b) // = b*b*R*R - fp503X2AddLazy(&asq, &asq, &bsq) // = (a^2 + b^2)*R*R - fp503MontgomeryReduce(&asq_plus_bsq.A, &asq) // = (a^2 + b^2)*R mod p - // Now asq_plus_bsq = a^2 + b^2 - - inv := asq_plus_bsq - inv.Mul(&asq_plus_bsq, &asq_plus_bsq) - inv.P34(&inv) - inv.Mul(&inv, &inv) - inv.Mul(&inv, &asq_plus_bsq) - - var ac FpElementX2 - fp503Mul(&ac, a, &inv.A) - fp503MontgomeryReduce(&dest.A, &ac) - - var minus_b FpElement - fp503SubReduced(&minus_b, &minus_b, b) - var minus_bc FpElementX2 - fp503Mul(&minus_bc, &minus_b, &inv.A) - fp503MontgomeryReduce(&dest.B, &minus_bc) -} - -func (fp503Ops) Square(dest, x *Fp2Element) { - a := &x.A - b := &x.B - - // We want to compute - // - // (a + bi)*(a + bi) = (a^2 - b^2) + 2abi. - - var a2, a_plus_b, a_minus_b FpElement - fp503AddReduced(&a2, a, a) // = a*R + a*R = 2*a*R - fp503AddReduced(&a_plus_b, a, b) // = a*R + b*R = (a+b)*R - fp503SubReduced(&a_minus_b, a, b) // = a*R - b*R = (a-b)*R - - var asq_minus_bsq, ab2 FpElementX2 - fp503Mul(&asq_minus_bsq, &a_plus_b, &a_minus_b) // = (a+b)*(a-b)*R*R = (a^2 - b^2)*R*R - fp503Mul(&ab2, &a2, b) // = 2*a*b*R*R - - fp503MontgomeryReduce(&dest.A, &asq_minus_bsq) // = (a^2 - b^2)*R mod p - fp503MontgomeryReduce(&dest.B, &ab2) // = 2*a*b*R mod p -} - -// In case choice == 1, performs following swap in constant time: -// xPx <-> xQx -// xPz <-> xQz -// Otherwise returns xPx, xPz, xQx, xQz unchanged -func (fp503Ops) CondSwap(xPx, xPz, xQx, xQz *Fp2Element, choice uint8) { - fp503ConditionalSwap(&xPx.A, &xQx.A, choice) - fp503ConditionalSwap(&xPx.B, &xQx.B, choice) - fp503ConditionalSwap(&xPz.A, &xQz.A, choice) - fp503ConditionalSwap(&xPz.B, &xQz.B, choice) -} - -// Converts values in x.A and x.B to Montgomery domain -// x.A = x.A * R mod p -// x.B = x.B * R mod p -// Performs v = v*R^2*R^(-1) mod p, for both x.A and x.B -func (fp503Ops) ToMontgomery(x *Fp2Element) { - var aRR FpElementX2 - - // convert to montgomery domain - fp503Mul(&aRR, &x.A, &p503R2) // = a*R*R - fp503MontgomeryReduce(&x.A, &aRR) // = a*R mod p - fp503Mul(&aRR, &x.B, &p503R2) - fp503MontgomeryReduce(&x.B, &aRR) -} - -// Converts values in x.A and x.B from Montgomery domain -// a = x.A mod p -// b = x.B mod p -// -// After returning from the call x is not modified. -func (fp503Ops) FromMontgomery(x *Fp2Element, out *Fp2Element) { - var aR FpElementX2 - - // convert from montgomery domain - // TODO: make fpXXXMontgomeryReduce use stack instead of reusing aR - // so that we don't have do this copy here - copy(aR[:], x.A[:]) - fp503MontgomeryReduce(&out.A, &aR) // = a mod p in [0, 2p) - fp503StrongReduce(&out.A) // = a mod p in [0, p) - for i := range aR { - aR[i] = 0 - } - copy(aR[:], x.B[:]) - fp503MontgomeryReduce(&out.B, &aR) - fp503StrongReduce(&out.B) -} - -//------------------------------------------------------------------------------ -// Prime Field -//------------------------------------------------------------------------------ - -// Represents an element of the prime field F_p. -type primeFieldElement struct { - // This field element is in Montgomery form, so that the value `A` is - // represented by `aR mod p`. - A FpElement -} - -// Set dest = lhs * rhs. -// -// Allowed to overlap lhs or rhs with dest. -// -// Returns dest to allow chaining operations. -func (dest *primeFieldElement) Mul(lhs, rhs *primeFieldElement) *primeFieldElement { - a := &lhs.A // = a*R - b := &rhs.A // = b*R - - var ab FpElementX2 - fp503Mul(&ab, a, b) // = a*b*R*R - fp503MontgomeryReduce(&dest.A, &ab) // = a*b*R mod p - - return dest -} - -// Set dest = x^(2^k), for k >= 1, by repeated squarings. -// -// Allowed to overlap x with dest. -// -// Returns dest to allow chaining operations. -func (dest *primeFieldElement) Pow2k(x *primeFieldElement, k uint8) *primeFieldElement { - dest.Mul(x, x) - for i := uint8(1); i < k; i++ { - dest.Mul(dest, dest) - } - - return dest -} - -// Set dest = x^((p-3)/4). If x is square, this is 1/sqrt(x). -// Uses variation of sliding-window algorithm from with window size -// of 5 and least to most significant bit sliding (left-to-right) -// See HAC 14.85 for general description. -// -// Allowed to overlap x with dest. -// -// Returns dest to allow chaining operations. -func (dest *primeFieldElement) P34(x *primeFieldElement) *primeFieldElement { - // Sliding-window strategy computed with etc/scripts/sliding_window_strat_calc.py - // - // This performs sum(powStrategy) + 1 squarings and len(lookup) + len(mulStrategy) - // multiplications. - powStrategy := []uint8{1, 12, 5, 5, 2, 7, 11, 3, 8, 4, 11, 4, 7, 5, 6, 3, 7, 5, 7, 2, 12, 5, 6, 4, 6, 8, 6, 4, 7, 5, 5, 8, 5, 8, 5, 5, 8, 9, 3, 6, 2, 10, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3} - mulStrategy := []uint8{0, 12, 11, 10, 0, 1, 8, 3, 7, 1, 8, 3, 6, 7, 14, 2, 14, 14, 9, 0, 13, 9, 15, 5, 12, 7, 13, 7, 15, 6, 7, 9, 0, 5, 7, 6, 8, 8, 3, 7, 0, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3} - - // Precompute lookup table of odd multiples of x for window - // size k=5. - lookup := [16]primeFieldElement{} - xx := &primeFieldElement{} - xx.Mul(x, x) - lookup[0] = *x - for i := 1; i < 16; i++ { - lookup[i].Mul(&lookup[i-1], xx) - } - - // Now lookup = {x, x^3, x^5, ... } - // so that lookup[i] = x^{2*i + 1} - // so that lookup[k/2] = x^k, for odd k - *dest = lookup[mulStrategy[0]] - for i := uint8(1); i < uint8(len(powStrategy)); i++ { - dest.Pow2k(dest, powStrategy[i]) - dest.Mul(dest, &lookup[mulStrategy[i]]) - } - - return dest -} diff --git a/dh/sidh/p503/isogeny_test.go b/dh/sidh/p503/isogeny_test.go deleted file mode 100644 index 38fad41..0000000 --- a/dh/sidh/p503/isogeny_test.go +++ /dev/null @@ -1,101 +0,0 @@ -package p503 - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - "testing" -) - -func TestFourIsogenyVersusSage(t *testing.T) { - var xR, xP4, resPhiXr, expPhiXr ProjectivePoint - var phi = Newisogeny4(kFieldOps) - - // Given 4-torsion point on E, constructs a four-isogeny phi. Then evaluates - // point xR on the isogeny and compares with expected result. - // Values generated with reference implementation. - - xP4 = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0xD00E20EC32B0EC29, 0xB931E12F6B486A34, 0x96EFFCAEC541E83F, 0x415729120E95D243, 0xB15DADFFBC7986EB, 0x27E7697979D482AC, 0xB269E255C3C11421, 0x35DFF53EF1BDE4}, - B: FpElement{0x691F8D69E98BBF40, 0xAB3894C2F436C73, 0x6CE884D45D785C50, 0xBCDE642D761476C0, 0x8023EF2FCF4C9506, 0x6E3914CFCA94C8A0, 0x8AFE4F1C54EB8744, 0x163227D8890C30}, - }, - Z: Fp2Element{ - A: FpElement{0x38B48A08355253FD, 0x457A001F6F522A58, 0x1959F48231C94070, 0xDF3B4C55A3FF1202, 0x3835E8FB47E9B93F, 0x84320E41E65889B5, 0x6D4AA6D38651BE7E, 0xF50448746FF64}, - B: FpElement{0xEBBCCCBB347E448C, 0xFBC721B5DB2103C9, 0x54FD31DF0C538F18, 0xDE7B3C6CBB60C5BD, 0x86B664DCF5F4B272, 0x705CFC301B13DCD6, 0xFD250579C9257778, 0x366F73666C6C92}, - }, - } - xR = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x6F50E690932A1473, 0x3EC8EE10B576C790, 0x5CABB067D0648B46, 0x77EA840A4219753C, 0xBFEE6EAB2073A69A, 0x845637223AB3687B, 0x20294B44CBDC9F34, 0x59C58391A33D5C}, - B: FpElement{0x68832275EA18BDDC, 0x90039FCD522B6CCF, 0x43A97285E71B711A, 0xBCBFC2C3BCCF6135, 0xDE13C2E410DCF1FE, 0xB9B1243C7E4FC515, 0x3CE1C024813A61D, 0x2BED536959B2D}, - }, - Z: Fp2Element{ - A: FpElement{0x99C27A12675FD4CD, 0x856E300D657ADDE3, 0x156C170BB8983CD3, 0x6A366F8BA2FD7805, 0xE922609C4B80E4A4, 0xAC5A1D2EBE7F2A9A, 0x2E732DAF59AE4A03, 0x6AC91B99882D54}, - B: FpElement{0x909A822C8536612D, 0xBF579BF499C34C2D, 0xE2FAD61D94E1E60F, 0x37CB4E1F0A819D5F, 0xDBD36EA4FC053430, 0x28F3805ECA4730D8, 0x33F47EAF9ED8CEA2, 0x24FC2437192954}, - }, - } - expPhiXr = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x2E2D7C96BB057AE9, 0x58FF5432A90EA157, 0x6EED2543FED809C7, 0xF721E3657B17C6D3, 0xC9F8EBED3E1430AF, 0xA94DAFEC2ED7275A, 0xFC8A869CF993A64D, 0x45C8B4291BC602}, - B: FpElement{0xD5730CA5DA535196, 0x958D80511DCD695F, 0xCFDCAA016F0D6AF, 0x176FAA4414FC230B, 0x61A5CDD045B67365, 0x13AC43A5E7F0E446, 0x7BCABE9E555C2729, 0x2CA6A01B26BFEB}, - }, - Z: Fp2Element{ - A: FpElement{0x684A5999FCD11607, 0x3D0057EA6B62FC92, 0x692895B2D37F8EAA, 0xF0BB08106CCF7FDF, 0x3A521D25A431C5CF, 0x8F8DCB43E0BD2475, 0x9CF6266E32D712D3, 0x3B98B6D5C0B377}, - B: FpElement{0x8F4E4EA61ACA375, 0xE8DF168DA6349D03, 0x8DFD68ABA4AB08CC, 0x5352A227C5C6D59C, 0x45750EB03218D4D6, 0x71E2AD1F130DB05E, 0x64F35BBA642804EC, 0x26542493BF5F1C}, - }, - } - - phi.GenerateCurve(&xP4) - resPhiXr = phi.EvaluatePoint(&xR) - if !VartimeEqProjFp2(&expPhiXr, &resPhiXr) { - t.Error("\nExpected\n", expPhiXr.ToAffine(kCurveOps), "\nfound\n", resPhiXr.ToAffine(kCurveOps)) - } -} - -func TestThreeIsogenyVersusSage(t *testing.T) { - var xR, xP3, resPhiXr, expPhiXr ProjectivePoint - var phi = Newisogeny3(kFieldOps) - - // Given 3-torsion point on E, constructs a three-isogeny phi. Then evaluates - // point xR on the isogeny and compares with expected result. - // Values generated with reference implementation. - - xP3 = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x43C64B1158DE7ED, 0xC522F8AB7DCC9247, 0xC5BFCC8EA95E9F4D, 0xA6DFCE67C53F63BC, 0x9C6329D65EBBBE44, 0x91949F2E9864BD5A, 0xC9AE7B8B0435B0AF, 0x1607E735F9E10}, - B: FpElement{0x3EEFA1A8B5D59CD9, 0x1ED7264A82282E14, 0x253309D0531054E1, 0x7557CC9966B63AB1, 0xAAB3B77A0CF3D9C, 0xF9BE0DC1977358F4, 0xC5B7AE198CF22874, 0x3250464B34AAD1}, - }, - Z: Fp2Element{ - A: FpElement{0xC06D37BCBBD98418, 0x1C7C9E348A880023, 0xB1F61CA46EA815FD, 0x7E0E5F01EAB9D7B6, 0xE8737A5EF457E188, 0xBD228FDA0BAF18D8, 0xAB7823AF7BAFD785, 0x2BCA7CCFFC1DDA}, - B: FpElement{0xBC34D39B7CBF3EDC, 0x882C3AFC4011C8E8, 0x68A2D74B0FBA196E, 0x810E59E7DD937844, 0xE796B5D4BFC3982F, 0xC7D23388B8E91883, 0x552B783D3986109F, 0x1337962318DFC0}, - }, - } - - xR = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0xBA300F2F1C010480, 0xE196ACEE08FEA8BA, 0xC1B8AB47C5D6D9A, 0x2CDFF1E375E5FAFC, 0x2D55CBA6472829AF, 0xE03ECA628015CA0E, 0xD1055B779C2DCC6C, 0x7F915F81CAF33}, - B: FpElement{0x5179F86B4F63CA45, 0x8CF33AD2D0D7E409, 0xE9065B70EB5F8680, 0xFBA717809FF35FE, 0x8E31E6EF3CAD154C, 0x65907A2B38A0B673, 0x9E5A4FFCF1F7E74, 0x3170F0C18D5F96}, - }, - Z: Fp2Element{ - A: FpElement{0x1F48F3A2DFB1C73B, 0x3E35C8CD0752F9A4, 0x88601205D0B6B8C0, 0xCFF48E40A9C200CD, 0x10E6964543C6195C, 0x6B8F141796914E13, 0xA7B5F96629DF495E, 0x6600DB36C90874}, - B: FpElement{0xAB54D5B8247FE6CA, 0xD5EE5EAE7C19E9B4, 0x16CB352BA75CB7EF, 0x6D651A77FEB51C5E, 0x2D72F65AC9D39E8A, 0xE10F942CEAD9C7EA, 0x36A5A27BE681CE7A, 0x1C500AA0D9A62F}, - }, - } - - expPhiXr = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x61B04752330F7FFF, 0x67F7FADAE5093E06, 0xB665F1E8F70118C6, 0x4F529F9BB30AE6A0, 0xD38E0FC09717C6D1, 0xB7886970ADE8584B, 0x73D66E118BAA193C, 0x4604C634755CFB}, - B: FpElement{0x65CCBE0938AB5A99, 0x1F23B14E1548E3BC, 0x2A565624008051D8, 0xC45D118553BEA2E5, 0x7E2C027737E386EA, 0xF8EC1668C4C09CFB, 0x24CBE8F9D424021D, 0x62E99144A24A6}, - }, - Z: Fp2Element{ - A: FpElement{0x71D9A198BB845CCA, 0xB2D0A8D2168F4399, 0x9C85368AF08AC7E1, 0x76D71A16B7F4B966, 0x60821CCED03DE7DB, 0x80D404686B651216, 0x8489AF1E2E14BF8E, 0x370781CDE810FE}, - B: FpElement{0xB12EE10B6B80F65B, 0xC4C1CD99C671118D, 0xB84A2C8B2C153F37, 0x9170BAE0CE11B7A8, 0xF38DE8F9AF1BF991, 0x88612A07E7F7015A, 0x9611B2C68B94BC68, 0x5BCFB00EC5DE0}, - }, - } - - phi.GenerateCurve(&xR) - resPhiXr = phi.EvaluatePoint(&xP3) - - if !VartimeEqProjFp2(&expPhiXr, &resPhiXr) { - t.Error("\nExpected\n", expPhiXr.ToAffine(kCurveOps), "\nfound\n", resPhiXr.ToAffine(kCurveOps)) - } -} diff --git a/dh/sidh/p503/utils_test.go b/dh/sidh/p503/utils_test.go deleted file mode 100644 index 45b02f1..0000000 --- a/dh/sidh/p503/utils_test.go +++ /dev/null @@ -1,335 +0,0 @@ -package p503 - -// Tools used for testing and debugging - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - "math/big" - "math/rand" - "reflect" - "testing/quick" -) - -/* ------------------------------------------------------------------------- - Underlying field configuration - -------------------------------------------------------------------------*/ -var ( - kFieldOps = FieldOperations() - kParams = &SidhParams{ - Op: kFieldOps, - OneFp2: P503OneFp2, - HalfFp2: P503HalfFp2, - Bytelen: P503_Bytelen, - } - kCurveOps = &CurveOperations{Params: kParams} -) - -/* ------------------------------------------------------------------------- - Configure testing/quick - -------------------------------------------------------------------------*/ -var ( - quickCheckScaleFactor = uint8(3) - quickCheckConfig = &quick.Config{MaxCount: (1 << (12 + quickCheckScaleFactor))} -) - -/* ------------------------------------------------------------------------- - Structure used by tests - -------------------------------------------------------------------------*/ -type GeneratedTestParams struct { - Point ProjectivePoint - Cparam ProjectiveCurveParameters - ExtElem Fp2Element -} - -// A = 8752234765512331234913716743014562460822083005386252003333602919474238975785850965349950219277942402920758585086620525443539725921333735154674119646075*i + 6339624979889725406021454983012408976766782818694212228554611573314701271183857175866122275755278397694585249002282183018114967373119429936587424396917 -var curve_A = Fp2Element{ - A: FpElement{0xd9816986a543095f, 0xa78cb1d7217bec21, 0x9595dc97b74ea70, 0x9120a1da6b42797d, 0x59ef9d903f74e47c, 0x4c58a4cdc45b6d0b, 0x816d5213aaf7ee6d, 0x3892fee6bb7343}, - B: FpElement{0x28c5288acbedf11b, 0x2143a438c86f6c68, 0x7cb5c4ae9c4c8e34, 0xb478aea445eed48b, 0x24d5c175776db478, 0x234582f8676c0ebe, 0x56234267b625fb08, 0x2c6e58d84b1192}} - -// C = 10458464853790890798085664692909194316288127038910691163573355876336993883402795907795767791362493831987298578966325154262747805705783782806176495638177*i + 7770984753616185271325854825309278833018655051139367603077592443785629339985729818288672809062782315510526648882226172896710704020683893684611137718845 -var curve_C = Fp2Element{ - A: FpElement{0xe05948236f2f913b, 0xc45da9ad1219a255, 0x7a568972a32fc1d0, 0x30f00bdd7071c3b1, 0x3b761b8dac2c98bc, 0x760f21b2179737b6, 0x13217e6656a13476, 0x2606b798e685aa}, - B: FpElement{0x1c0171f78820052e, 0x440b7f7087e57140, 0xe0510c07b31b0e96, 0xd0cf489b2ac4aea9, 0x4fb328f1c1fdf783, 0xb3b4912342951cb7, 0x70a4b64e81961c42, 0x33eed63cf07181}} - -// x(P) = 9720237205826983370867050298878715935679372786589878620121159082290288918688002583435964840822877971257659901481591644347943354235932355923042390796255*i + 634577413124118560098123299804750904956499531431297942628887930019161512075536652691244843248133437326050395005054997679717801535474938466995392156605 -var affine_xP = Fp2Element{ - A: FpElement{0xb606d954d407faf2, 0x58a1ef6cd213a203, 0x9823b55033e62f7b, 0x59cafc060d5e25a1, 0x529685f1753526fc, 0xc2eac3d219989c7d, 0xc5e30c75dfd343a0, 0x378285adc968a0}, - B: FpElement{0x6670f36db977b9da, 0xa07e2fdda5e1a7f0, 0xf367a7a722aed87d, 0x6c269e06d595cd10, 0x8379aa6092d87700, 0x57276ce3557ee7ae, 0xac8107bfbcd28993, 0x3d6f98869617a7}} - -// x(Q) = 613162677562606602867371958793876971530136728660199185642812914351735322828980793298955764087721218995329689800176835576008483782305021671417330230966*i + 12939479853552958669415184882894789433224467828463058020095712989798268661016843892597050485554155971441665589419365957826417334087966365414056706471602 -var affine_xQ = Fp2Element{ - A: FpElement{0xd3d14533cb0db45c, 0xdaf10b9f5fb037cf, 0x9562c31985823562, 0xb79b75e2bf5635a5, 0x83d38fb1669c2d9, 0x5e67117a35a57cbd, 0x4b94ed6c3cbf54a4, 0x3f47706b62778d}, - B: FpElement{0x1c766c0e7ed612d6, 0x2f3b42979e8efd86, 0xd82bac0006415ee7, 0x20cfe3bec0970042, 0x8f6628807e862bf9, 0xac4f82d13fddd9c5, 0x70b756e4bac1fa85, 0x350c02508e50dc}} - -var affine_xPmQ = Fp2Element{ - A: FpElement{0x7295ac0e8a5531c8, 0xc02afbef6cdf51a8, 0x84d0c1bb8d80624f, 0x26abbf06c61e814b, 0xada277883fbdae07, 0x63b6739db68df3a7, 0x3554670381bcfcc6, 0x33419be255bbc6}, - B: FpElement{0xff9df35102da997a, 0xf9b920b2d8bd6210, 0x43d1514920e73bfb, 0x624c6fd6ef16da74, 0xeb535968ed0d1286, 0x9243e6ce29a636e6, 0x1849ed96cb7940e0, 0x1e4b495933b675}} - -var affine_xP2 = Fp2Element{ - A: FpElement{0x4e1133c2b3855902, 0x875a775c67597fbb, 0xd17eb74254141abb, 0x1d5a464a4f3391f5, 0x24405c332811d007, 0x7e47e3eb489a7372, 0x65b130dfd9efe605, 0xfa69fac179803}, - B: FpElement{0x329f5322e1be51ee, 0x9004dca8132ebd6f, 0x7cd87e447ca8a7b6, 0x10a6ec02c38ce69e, 0x8cef2ed7d112ac46, 0x5f385a9fc4b57cd7, 0x68a366354fe7a32e, 0x2223c1455486ac}} - -var affine_xP3 = Fp2Element{ - A: FpElement{0x74a2894cccbe287d, 0xa50e3ec842e13fce, 0xd42ea4d3f1b7ad0b, 0xa4943d50d306f99e, 0xf83e9c0955b08c33, 0xffd8e313402b9380, 0x967b315db0b2e6e, 0x3a0945883df3b4}, - B: FpElement{0xa9f610420a81c5ba, 0xbeb84b3ded2b4e75, 0x9fd6cea494470a70, 0x2fb0075e71900b0e, 0x63a0beb6abf3ca3d, 0xeb3e171798959f2e, 0x2209801eb702d40e, 0x36f8c4603e0fdb}} - -var affine_xP4 = Fp2Element{ - A: FpElement{0x4eb695d34b46be8f, 0xfb5e76c58585f2d2, 0xa41f8aafa6dbb531, 0x4db82f5db5cfd144, 0x14dab0e3200cbba0, 0x430381706a279f81, 0xdf6707a57161f81, 0x44740f17197c3}, - B: FpElement{0xa2473705cdb6d4e9, 0xfa3cd67b9c15502c, 0xf0928166d0c5cee1, 0x6150aba0c874faaa, 0x6c0b18d6d92f9034, 0xcff71d340fc1e72e, 0x19a47027af917587, 0x25ed4bad443b8f}} - -var affine_xP9 = Fp2Element{ - A: FpElement{0x112da30e288217e0, 0x5b336d527320a5f7, 0xbbf4d9403b68e3c6, 0x55eccb31c40b359c, 0x8907129ab69b3203, 0x69cc8c750125a915, 0xa41a38e6f530c0e1, 0xbe68e23af1b8d}, - B: FpElement{0x472c603765964213, 0xe4e64995b0769754, 0x4515583c74a6dd24, 0xff7c57f5818363a2, 0xbeaeb24662a92177, 0x8a54fa61fbf24c68, 0xa85542049eb45e12, 0x2b54caf655e285}} - -// m = 3904534670189250445536401319770569077681088033069864532895 -var mScalarBytes = [...]uint8{0x9f, 0x3b, 0xe7, 0xf9, 0xf4, 0x7c, 0xe6, 0xce, 0x79, 0x3e, 0x3d, 0x9f, 0x9f, 0x3b, 0xe7, 0xf9, 0xf4, 0x7c, 0xe6, 0xce, 0x79, 0x3e, 0x3d, 0x9f} - -var affine_xaP = Fp2Element{ - A: FpElement{0x100a82c2be58e28b, 0x70ee7b57f40d9103, 0xb9f21d6327411cbb, 0x976b2a65166591cb, 0x35435bd4614ca404, 0x15f862a9c6f51469, 0x14d9ccfe634f374a, 0x31234988b0766c}, - B: FpElement{0x323a3a13113b35f8, 0xc949dad174586c8f, 0x1c5ed3b1263143c, 0x13ba9870c9b5bab8, 0x79fb89a31cfe7f19, 0xa8af6d4b5d947ed2, 0xcff00f80d7b67a56, 0xfdfcb136bff75}} - -// Inputs for testing 3-point-ladder -var threePointLadderInputs = []ProjectivePoint{ - // x(P) - ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x43941FA9244C059E, 0xD1F337D076941189, 0x6B6A8B3A8763C96A, 0x6DF569708D6C9482, 0x487EE5707A52F4AA, 0xDE396F6E2559689E, 0xE5EE3895A8991469, 0x2B0946695790A8}, - B: FpElement{0xAB552C0FDAED092E, 0x7DF895E43E7DCB1C, 0x35C700E761920C4B, 0xCC5807DD70DC117A, 0x0884039A5A8DB18A, 0xD04620B3D0738052, 0xA200835605138F10, 0x3FF2E59B2FDC6A}}, - Z: P503OneFp2, - }, - // x(Q) - ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x77015826982BA1FD, 0x44024489673471E4, 0x1CAA2A5F4D5DA63B, 0xA183C07E50738C01, 0x8B97782D4E1A0DE6, 0x9B819522FBC38280, 0x0BDA46A937FB7B8A, 0x3B3614305914DF}, - B: FpElement{0xBF0366E97B3168D9, 0xAA522AC3879CEF0F, 0x0AF5EC975BD035C8, 0x1F26FEE7BBAC165C, 0xA0EE6A637724A6AB, 0xFB52101E36BA3A38, 0xD29CF5E376E17376, 0x1374A50DF57071}}, - Z: P503OneFp2, - }, - // x(P-Q) - ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0xD99279BBD41EA559, 0x35CF18E72F578214, 0x90473B1DC77F73E8, 0xBFFEA930B25D7F66, 0xFD558EA177B900B2, 0x7CFAD273A782A23E, 0x6B1F610822E0F611, 0x26D2D2EF9619B5}, - B: FpElement{0x534F83651CBCC75D, 0x591FB4757AED5D08, 0x0B04353D40BED542, 0x829A94703AAC9139, 0x0F9C2E6D7663EB5B, 0x5D2D0F90C283F746, 0x34C872AA12A7676E, 0x0ECDB605FBFA16}}, - Z: P503OneFp2, - }, -} -var curve = ProjectiveCurveParameters{A: curve_A, C: curve_C} - -// prime p503 -var p503BigIntPrime, _ = new(big.Int).SetString("13175843156907117380839252916199345042492186767578363998445663477035843932020761233518914911546024351608607150390087656982982306331019593961154237431807", 10) - -/* ------------------------------------------------------------------------- - Values used by benchmarking tools - -------------------------------------------------------------------------*/ - -// Package-level storage for this field element is intended to deter -// compiler optimizations. -var ( - benchmarkFpElement FpElement - benchmarkFpElementX2 FpElementX2 - bench_x = FpElement{17026702066521327207, 5108203422050077993, 10225396685796065916, 11153620995215874678, 6531160855165088358, 15302925148404145445, 1248821577836769963, 9789766903037985294, 7493111552032041328, 10838999828319306046, 18103257655515297935, 27403304611634} - bench_y = FpElement{4227467157325093378, 10699492810770426363, 13500940151395637365, 12966403950118934952, 16517692605450415877, 13647111148905630666, 14223628886152717087, 7167843152346903316, 15855377759596736571, 4300673881383687338, 6635288001920617779, 30486099554235} - bench_z = FpElementX2{1595347748594595712, 10854920567160033970, 16877102267020034574, 12435724995376660096, 3757940912203224231, 8251999420280413600, 3648859773438820227, 17622716832674727914, 11029567000887241528, 11216190007549447055, 17606662790980286987, 4720707159513626555, 12887743598335030915, 14954645239176589309, 14178817688915225254, 1191346797768989683, 12629157932334713723, 6348851952904485603, 16444232588597434895, 7809979927681678066, 14642637672942531613, 3092657597757640067, 10160361564485285723, 240071237} -) - -/* ------------------------------------------------------------------------- - Helpers - -------------------------------------------------------------------------*/ - -// Given xP = x(P), xQ = x(Q), and xPmQ = x(P-Q), compute xR = x(P+Q). -// -// Returns xR to allow chaining. Safe to overlap xP, xQ, xR. -func AddProjFp2(xP, xQ, xPmQ *ProjectivePoint) ProjectivePoint { - // Algorithm 1 of Costello-Smith. - var v0, v1, v2, v3, v4 Fp2Element - var xR ProjectivePoint - kFieldOps.Add(&v0, &xP.X, &xP.Z) // X_P + Z_P - kFieldOps.Sub(&v1, &xQ.X, &xQ.Z) - kFieldOps.Mul(&v1, &v1, &v0) // (X_Q - Z_Q)(X_P + Z_P) - kFieldOps.Sub(&v0, &xP.X, &xP.Z) // X_P - Z_P - kFieldOps.Add(&v2, &xQ.X, &xQ.Z) - kFieldOps.Mul(&v2, &v2, &v0) // (X_Q + Z_Q)(X_P - Z_P) - kFieldOps.Add(&v3, &v1, &v2) - kFieldOps.Square(&v3, &v3) // 4(X_Q X_P - Z_Q Z_P)^2 - kFieldOps.Sub(&v4, &v1, &v2) - kFieldOps.Square(&v4, &v4) // 4(X_Q Z_P - Z_Q X_P)^2 - kFieldOps.Mul(&v0, &xPmQ.Z, &v3) // 4X_{P-Q}(X_Q X_P - Z_Q Z_P)^2 - kFieldOps.Mul(&xR.Z, &xPmQ.X, &v4) // 4Z_{P-Q}(X_Q Z_P - Z_Q X_P)^2 - xR.X = v0 - return xR -} - -// Given xP = x(P) and cached curve parameters Aplus2C = A + 2*C, C4 = 4*C, -// compute xQ = x([2]P). -// -// Returns xQ to allow chaining. Safe to overlap xP, xQ. -func DoubleProjFp2(xP *ProjectivePoint, Aplus2C, C4 *Fp2Element) ProjectivePoint { - // Algorithm 2 of Costello-Smith, amended to work with projective curve coefficients. - var v1, v2, v3, xz4 Fp2Element - var xQ ProjectivePoint - kFieldOps.Add(&v1, &xP.X, &xP.Z) // (X+Z)^2 - kFieldOps.Square(&v1, &v1) - kFieldOps.Sub(&v2, &xP.X, &xP.Z) // (X-Z)^2 - kFieldOps.Square(&v2, &v2) - kFieldOps.Sub(&xz4, &v1, &v2) // 4XZ = (X+Z)^2 - (X-Z)^2 - kFieldOps.Mul(&v2, &v2, C4) // 4C(X-Z)^2 - kFieldOps.Mul(&xQ.X, &v1, &v2) // 4C(X+Z)^2(X-Z)^2 - kFieldOps.Mul(&v3, &xz4, Aplus2C) // 4XZ(A + 2C) - kFieldOps.Add(&v3, &v3, &v2) // 4XZ(A + 2C) + 4C(X-Z)^2 - kFieldOps.Mul(&xQ.Z, &v3, &xz4) // (4XZ(A + 2C) + 4C(X-Z)^2)4XZ - // Now (xQ.x : xQ.z) - // = (4C(X+Z)^2(X-Z)^2 : (4XZ(A + 2C) + 4C(X-Z)^2)4XZ ) - // = ((X+Z)^2(X-Z)^2 : (4XZ((A + 2C)/4C) + (X-Z)^2)4XZ ) - // = ((X+Z)^2(X-Z)^2 : (4XZ((a + 2)/4) + (X-Z)^2)4XZ ) - return xQ -} - -// Given x(P) and a scalar m in little-endian bytes, compute x([m]P) using the -// Montgomery ladder. This is described in Algorithm 8 of Costello-Smith. -// -// This function's execution time is dependent only on the byte-length of the -// input scalar. All scalars of the same input length execute in uniform time. -// The scalar can be padded with zero bytes to ensure a uniform length. -// -// Safe to overlap the source with the destination. -func ScalarMult(curve *ProjectiveCurveParameters, xP *ProjectivePoint, scalar []uint8) ProjectivePoint { - var x0, x1, tmp ProjectivePoint - var Aplus2C, C4 Fp2Element - - kFieldOps.Add(&Aplus2C, &curve.C, &curve.C) // = 2*C - kFieldOps.Add(&C4, &Aplus2C, &Aplus2C) // = 4*C - kFieldOps.Add(&Aplus2C, &Aplus2C, &curve.A) // = 2*C + A - - x0.X = P503OneFp2 - x1 = *xP - - // Iterate over the bits of the scalar, top to bottom - prevBit := uint8(0) - for i := len(scalar) - 1; i >= 0; i-- { - scalarByte := scalar[i] - for j := 7; j >= 0; j-- { - bit := (scalarByte >> uint(j)) & 0x1 - kCurveOps.Params.Op.CondSwap(&x0.X, &x0.Z, &x1.X, &x1.Z, (bit ^ prevBit)) - //sProjectivePointConditionalSwap(&x0, &x1, (bit ^ prevBit)) - tmp = DoubleProjFp2(&x0, &Aplus2C, &C4) - x1 = AddProjFp2(&x0, &x1, xP) - x0 = tmp - prevBit = bit - } - } - // now prevBit is the lowest bit of the scalar - kCurveOps.Params.Op.CondSwap(&x0.X, &x0.Z, &x1.X, &x1.Z, prevBit) - return x0 -} - -// Returns true if lhs = rhs. Takes variable time. -func VartimeEqFp2(lhs, rhs *Fp2Element) bool { - a := *lhs - b := *rhs - - fp503StrongReduce(&a.A) - fp503StrongReduce(&a.B) - fp503StrongReduce(&b.A) - fp503StrongReduce(&b.B) - - eq := true - for i := 0; i < len(a.A) && eq; i++ { - eq = eq && (a.A[i] == b.A[i]) - eq = eq && (a.B[i] == b.B[i]) - } - return eq -} - -// Returns true if lhs = rhs. Takes variable time. -func VartimeEqProjFp2(lhs, rhs *ProjectivePoint) bool { - var t0, t1 Fp2Element - kFieldOps.Mul(&t0, &lhs.X, &rhs.Z) - kFieldOps.Mul(&t1, &lhs.Z, &rhs.X) - return VartimeEqFp2(&t0, &t1) -} - -func (GeneratedTestParams) generateFp2p503(rand *rand.Rand) Fp2Element { - // Generation strategy: low limbs taken from [0,2^64); high limb - // taken from smaller range - // - // Size hint is ignored since all elements are fixed size. - // - // Field elements taken in range [0,2p). Emulate this by capping - // the high limb by the top digit of 2*p-1: - // - // sage: (2*p-1).digits(2^64)[-1] - // 36255204122967100 - // - // This still allows generating values >= 2p, but hopefully that - // excess is OK (and if it's not, we'll find out, because it's for - // testing...) - // - highLimb := rand.Uint64() % 36255204122967100 - fpElementGen := func() FpElement { - return FpElement{ - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - highLimb, - } - } - return Fp2Element{A: fpElementGen(), B: fpElementGen()} -} - -func (c GeneratedTestParams) Generate(rand *rand.Rand, size int) reflect.Value { - return reflect.ValueOf( - GeneratedTestParams{ - ProjectivePoint{ - X: c.generateFp2p503(rand), - Z: c.generateFp2p503(rand), - }, - ProjectiveCurveParameters{ - A: c.generateFp2p503(rand), - C: c.generateFp2p503(rand), - }, - c.generateFp2p503(rand), - }) -} - -func (x primeFieldElement) Generate(rand *rand.Rand, size int) reflect.Value { - return reflect.ValueOf(primeFieldElement{A: new(GeneratedTestParams).generateFp2p503(rand).A}) -} - -// Convert an FpElement to a big.Int for testing. Because this is only -// for testing, no big.Int to FpElement conversion is provided. -func radix64ToBigInt(x []uint64) *big.Int { - radix := new(big.Int) - // 2^64 - radix.UnmarshalText(([]byte)("18446744073709551616")) - - base := new(big.Int).SetUint64(1) - val := new(big.Int).SetUint64(0) - tmp := new(big.Int) - - for _, xi := range x { - tmp.SetUint64(xi) - tmp.Mul(tmp, base) - val.Add(val, tmp) - base.Mul(base, radix) - } - - return val -} - -func toBigInt(x *FpElement) *big.Int { - // Convert from Montgomery form - return toBigIntFromMontgomeryForm(x) -} - -func toBigIntFromMontgomeryForm(x *FpElement) *big.Int { - // Convert from Montgomery form - a := FpElement{} - aR := FpElementX2{} - copy(aR[:], x[:]) // = a*R - fp503MontgomeryReduce(&a, &aR) // = a mod p in [0,2p) - fp503StrongReduce(&a) // = a mod p in [0,p) - return radix64ToBigInt(a[:]) -} diff --git a/dh/sidh/p751/arith_decl.go b/dh/sidh/p751/arith_decl.go deleted file mode 100644 index a67aa7a..0000000 --- a/dh/sidh/p751/arith_decl.go +++ /dev/null @@ -1,44 +0,0 @@ -// +build amd64,!noasm arm64,!noasm - -package p751 - -import . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - -// If choice = 0, leave x,y unchanged. If choice = 1, set x,y = y,x. -// If choice is neither 0 nor 1 then behaviour is undefined. -// This function executes in constant time. -//go:noescape -func fp751ConditionalSwap(x, y *FpElement, choice uint8) - -// Compute z = x + y (mod p). -//go:noescape -func fp751AddReduced(z, x, y *FpElement) - -// Compute z = x - y (mod p). -//go:noescape -func fp751SubReduced(z, x, y *FpElement) - -// Compute z = x + y, without reducing mod p. -//go:noescape -func fp751AddLazy(z, x, y *FpElement) - -// Compute z = x + y, without reducing mod p. -//go:noescape -func fp751X2AddLazy(z, x, y *FpElementX2) - -// Compute z = x - y, without reducing mod p. -//go:noescape -func fp751X2SubLazy(z, x, y *FpElementX2) - -// Compute z = x * y. -//go:noescape -func fp751Mul(z *FpElementX2, x, y *FpElement) - -// Compute Montgomery reduction: set z = x * R^{-1} (mod 2*p). -// It may destroy the input value. -//go:noescape -func fp751MontgomeryReduce(z *FpElement, x *FpElementX2) - -// Reduce a field element in [0, 2*p) to one in [0,p). -//go:noescape -func fp751StrongReduce(x *FpElement) diff --git a/dh/sidh/p751/arith_generic.go b/dh/sidh/p751/arith_generic.go deleted file mode 100644 index 2c5793c..0000000 --- a/dh/sidh/p751/arith_generic.go +++ /dev/null @@ -1,196 +0,0 @@ -// +build noasm !amd64,!arm64 - -package p751 - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/arith" - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" -) - -// Compute z = x + y (mod p). -func fp751AddReduced(z, x, y *FpElement) { - var carry uint64 - - // z=x+y % p751 - for i := 0; i < NumWords; i++ { - z[i], carry = Addc64(carry, x[i], y[i]) - } - - // z = z - p751x2 - carry = 0 - for i := 0; i < NumWords; i++ { - z[i], carry = Subc64(carry, z[i], p751x2[i]) - } - - // z = z + p751x2 - mask := uint64(0 - carry) - carry = 0 - for i := 0; i < NumWords; i++ { - z[i], carry = Addc64(carry, z[i], p751x2[i]&mask) - } -} - -// Compute z = x - y (mod p). -func fp751SubReduced(z, x, y *FpElement) { - var borrow uint64 - - for i := 0; i < NumWords; i++ { - z[i], borrow = Subc64(borrow, x[i], y[i]) - } - - mask := uint64(0 - borrow) - borrow = 0 - - for i := 0; i < NumWords; i++ { - z[i], borrow = Addc64(borrow, z[i], p751x2[i]&mask) - } -} - -// Conditionally swaps bits in x and y in constant time. -// mask indicates bits to be swaped (set bits are swapped) -// For details see "Hackers Delight, 2.20" -// -// Implementation doesn't actually depend on a prime field. -func fp751ConditionalSwap(x, y *FpElement, mask uint8) { - var tmp, mask64 uint64 - - mask64 = 0 - uint64(mask) - for i := 0; i < len(x); i++ { - tmp = mask64 & (x[i] ^ y[i]) - x[i] = tmp ^ x[i] - y[i] = tmp ^ y[i] - } -} - -// Perform Montgomery reduction: set z = x R^{-1} (mod 2*p) -// with R=2^768. Destroys the input value. -func fp751MontgomeryReduce(z *FpElement, x *FpElementX2) { - var carry, t, u, v uint64 - var uv Uint128 - var count int - - count = 5 // number of 0 digits in the least significat part of p751 + 1 - - for i := 0; i < NumWords; i++ { - for j := 0; j < i; j++ { - if j < (i - count + 1) { - uv = Mul64(z[j], p751p1[i-j]) - v, carry = Addc64(0, uv.L, v) - u, carry = Addc64(carry, uv.H, u) - t += carry - } - } - v, carry = Addc64(0, v, x[i]) - u, carry = Addc64(carry, u, 0) - t += carry - - z[i] = v - v = u - u = t - t = 0 - } - - for i := NumWords; i < 2*NumWords-1; i++ { - if count > 0 { - count-- - } - for j := i - NumWords + 1; j < NumWords; j++ { - if j < (NumWords - count) { - uv = Mul64(z[j], p751p1[i-j]) - v, carry = Addc64(0, uv.L, v) - u, carry = Addc64(carry, uv.H, u) - t += carry - } - } - v, carry = Addc64(0, v, x[i]) - u, carry = Addc64(carry, u, 0) - - t += carry - z[i-NumWords] = v - v = u - u = t - t = 0 - } - v, carry = Addc64(0, v, x[2*NumWords-1]) - z[NumWords-1] = v -} - -// Compute z = x * y. -func fp751Mul(z *FpElementX2, x, y *FpElement) { - var u, v, t uint64 - var carry uint64 - var uv Uint128 - - for i := uint64(0); i < NumWords; i++ { - for j := uint64(0); j <= i; j++ { - uv = Mul64(x[j], y[i-j]) - v, carry = Addc64(0, uv.L, v) - u, carry = Addc64(carry, uv.H, u) - t += carry - } - z[i] = v - v = u - u = t - t = 0 - } - - for i := NumWords; i < (2*NumWords)-1; i++ { - for j := i - NumWords + 1; j < NumWords; j++ { - uv = Mul64(x[j], y[i-j]) - v, carry = Addc64(0, uv.L, v) - u, carry = Addc64(carry, uv.H, u) - t += carry - } - z[i] = v - v = u - u = t - t = 0 - } - z[2*NumWords-1] = v -} - -// Compute z = x + y, without reducing mod p. -func fp751AddLazy(z, x, y *FpElement) { - var carry uint64 - for i := 0; i < NumWords; i++ { - z[i], carry = Addc64(carry, x[i], y[i]) - } -} - -// Compute z = x + y, without reducing mod p. -func fp751X2AddLazy(z, x, y *FpElementX2) { - var carry uint64 - for i := 0; i < 2*NumWords; i++ { - z[i], carry = Addc64(carry, x[i], y[i]) - } -} - -// Reduce a field element in [0, 2*p) to one in [0,p). -func fp751StrongReduce(x *FpElement) { - var borrow, mask uint64 - for i := 0; i < NumWords; i++ { - x[i], borrow = Subc64(borrow, x[i], p751[i]) - } - - // Sets all bits if borrow = 1 - mask = 0 - borrow - borrow = 0 - for i := 0; i < NumWords; i++ { - x[i], borrow = Addc64(borrow, x[i], p751[i]&mask) - } -} - -// Compute z = x - y, without reducing mod p. -func fp751X2SubLazy(z, x, y *FpElementX2) { - var borrow, mask uint64 - for i := 0; i < len(z); i++ { - z[i], borrow = Subc64(borrow, x[i], y[i]) - } - - // Sets all bits if borrow = 1 - mask = 0 - borrow - borrow = 0 - for i := NumWords; i < len(z); i++ { - z[i], borrow = Addc64(borrow, z[i], p751[i-NumWords]&mask) - } -} diff --git a/dh/sidh/p751/arith_test.go b/dh/sidh/p751/arith_test.go deleted file mode 100644 index 512989f..0000000 --- a/dh/sidh/p751/arith_test.go +++ /dev/null @@ -1,322 +0,0 @@ -package p751 - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - "math/big" - "testing" - "testing/quick" -) - -func TestPrimeFieldElementToBigInt(t *testing.T) { - // Chosen so that p < xR < 2p - x := primeFieldElement{A: FpElement{ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 140737488355328, - }} - // Computed using Sage: - // sage: p = 2^372 * 3^239 - 1 - // sage: R = 2^768 - // sage: from_radix_64 = lambda xs: sum((xi * (2**64)**i for i,xi in enumerate(xs))) - // sage: xR = from_radix_64([1]*11 + [2^47]) - // sage: assert(p < xR) - // sage: assert(xR < 2*p) - // sage: (xR / R) % p - xBig, _ := new(big.Int).SetString("4469946751055876387821312289373600189787971305258234719850789711074696941114031433609871105823930699680637820852699269802003300352597419024286385747737509380032982821081644521634652750355306547718505685107272222083450567982240", 10) - if xBig.Cmp(toBigInt(&x.A)) != 0 { - t.Error("Expected", xBig, "found", toBigInt(&x.A)) - } -} - -//------------------------------------------------------------------------------ -// Extended Field -//------------------------------------------------------------------------------ - -func TestOneFp2ToBytes(t *testing.T) { - var x = P751OneFp2 - var xBytes [188]byte - - kCurveOps.Fp2ToBytes(xBytes[:], &x) - if xBytes[0] != 1 { - t.Error("Expected 1, got", xBytes[0]) - } - for i := 1; i < 188; i++ { - if xBytes[i] != 0 { - t.Error("Expected 0, got", xBytes[0]) - } - } -} - -func TestFp2ElementToBytesRoundTrip(t *testing.T) { - roundTrips := func(x GeneratedTestParams) bool { - var xBytes [188]byte - var xPrime Fp2Element - kCurveOps.Fp2ToBytes(xBytes[:], &x.ExtElem) - kCurveOps.Fp2FromBytes(&xPrime, xBytes[:]) - - return VartimeEqFp2(&xPrime, &x.ExtElem) - } - - if err := quick.Check(roundTrips, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestFp2ElementMulDistributesOverAdd(t *testing.T) { - mulDistributesOverAdd := func(x, y, z GeneratedTestParams) bool { - // Compute t1 = (x+y)*z - t1 := new(Fp2Element) - kFieldOps.Add(t1, &x.ExtElem, &y.ExtElem) - kFieldOps.Mul(t1, t1, &z.ExtElem) - - // Compute t2 = x*z + y*z - t2 := new(Fp2Element) - t3 := new(Fp2Element) - kFieldOps.Mul(t2, &x.ExtElem, &z.ExtElem) - kFieldOps.Mul(t3, &y.ExtElem, &z.ExtElem) - kFieldOps.Add(t2, t2, t3) - - return VartimeEqFp2(t1, t2) - } - - if err := quick.Check(mulDistributesOverAdd, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestFp2ElementMulIsAssociative(t *testing.T) { - isAssociative := func(x, y, z GeneratedTestParams) bool { - // Compute t1 = (x*y)*z - t1 := new(Fp2Element) - kFieldOps.Mul(t1, &x.ExtElem, &y.ExtElem) - kFieldOps.Mul(t1, t1, &z.ExtElem) - - // Compute t2 = (y*z)*x - t2 := new(Fp2Element) - kFieldOps.Mul(t2, &y.ExtElem, &z.ExtElem) - kFieldOps.Mul(t2, t2, &x.ExtElem) - - return VartimeEqFp2(t1, t2) - } - - if err := quick.Check(isAssociative, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestFp2ElementSquareMatchesMul(t *testing.T) { - sqrMatchesMul := func(x GeneratedTestParams) bool { - // Compute t1 = (x*x) - t1 := new(Fp2Element) - kFieldOps.Mul(t1, &x.ExtElem, &x.ExtElem) - - // Compute t2 = x^2 - t2 := new(Fp2Element) - kFieldOps.Square(t2, &x.ExtElem) - - return VartimeEqFp2(t1, t2) - } - - if err := quick.Check(sqrMatchesMul, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestFp2ElementInv(t *testing.T) { - inverseIsCorrect := func(x GeneratedTestParams) bool { - z := new(Fp2Element) - kFieldOps.Inv(z, &x.ExtElem) - - // Now z = (1/x), so (z * x) * x == x - kFieldOps.Mul(z, z, &x.ExtElem) - kFieldOps.Mul(z, z, &x.ExtElem) - - return VartimeEqFp2(z, &x.ExtElem) - } - - // This is more expensive; run fewer tests - var quickCheckConfig = &quick.Config{MaxCount: (1 << (8 + quickCheckScaleFactor))} - if err := quick.Check(inverseIsCorrect, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestFp2ElementBatch3Inv(t *testing.T) { - batchInverseIsCorrect := func(x1, x2, x3 GeneratedTestParams) bool { - var x1Inv, x2Inv, x3Inv Fp2Element - kFieldOps.Inv(&x1Inv, &x1.ExtElem) - kFieldOps.Inv(&x2Inv, &x2.ExtElem) - kFieldOps.Inv(&x3Inv, &x3.ExtElem) - - var y1, y2, y3 Fp2Element - kCurveOps.Fp2Batch3Inv(&x1.ExtElem, &x2.ExtElem, &x3.ExtElem, &y1, &y2, &y3) - - return (VartimeEqFp2(&x1Inv, &y1) && VartimeEqFp2(&x2Inv, &y2) && VartimeEqFp2(&x3Inv, &y3)) - } - - // This is more expensive; run fewer tests - var quickCheckConfig = &quick.Config{MaxCount: (1 << (5 + quickCheckScaleFactor))} - if err := quick.Check(batchInverseIsCorrect, quickCheckConfig); err != nil { - t.Error(err) - } -} - -//------------------------------------------------------------------------------ -// Prime Field -//------------------------------------------------------------------------------ - -func TestPrimeFieldElementMulVersusBigInt(t *testing.T) { - mulMatchesBigInt := func(x, y primeFieldElement) bool { - z := new(primeFieldElement) - z.Mul(&x, &y) - - check := new(big.Int) - check.Mul(toBigInt(&x.A), toBigInt(&y.A)) - check.Mod(check, cln16prime) - - return check.Cmp(toBigInt(&z.A)) == 0 - } - - if err := quick.Check(mulMatchesBigInt, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func TestPrimeFieldElementP34VersusBigInt(t *testing.T) { - var p34, _ = new(big.Int).SetString("2588679435442326313244442059466701330356847411387267792529047419763669735170619711625720724140266678406138302904710050596300977994130638598261040117192787954244176710019728333589599932738193731745058771712747875468166412894207", 10) - p34MatchesBigInt := func(x primeFieldElement) bool { - z := new(primeFieldElement) - z.P34(&x) - - check := toBigInt(&x.A) - check.Exp(check, p34, cln16prime) - - return check.Cmp(toBigInt(&z.A)) == 0 - } - - // This is more expensive; run fewer tests - var quickCheckConfig = &quick.Config{MaxCount: (1 << (8 + quickCheckScaleFactor))} - if err := quick.Check(p34MatchesBigInt, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func BenchmarkFp2ElementMul(b *testing.B) { - z := &Fp2Element{A: bench_x, B: bench_y} - w := new(Fp2Element) - - for n := 0; n < b.N; n++ { - kFieldOps.Mul(w, z, z) - } -} - -func BenchmarkFp2ElementInv(b *testing.B) { - z := &Fp2Element{A: bench_x, B: bench_y} - w := new(Fp2Element) - - for n := 0; n < b.N; n++ { - kFieldOps.Inv(w, z) - } -} - -func BenchmarkFp2ElementSquare(b *testing.B) { - z := &Fp2Element{A: bench_x, B: bench_y} - w := new(Fp2Element) - - for n := 0; n < b.N; n++ { - kFieldOps.Square(w, z) - } -} - -func BenchmarkFp2ElementAdd(b *testing.B) { - z := &Fp2Element{A: bench_x, B: bench_y} - w := new(Fp2Element) - - for n := 0; n < b.N; n++ { - kFieldOps.Add(w, z, z) - } -} - -func BenchmarkFp2ElementSub(b *testing.B) { - z := &Fp2Element{A: bench_x, B: bench_y} - w := new(Fp2Element) - - for n := 0; n < b.N; n++ { - kFieldOps.Sub(w, z, z) - } -} - -func BenchmarkPrimeFieldElementMul(b *testing.B) { - z := &primeFieldElement{A: bench_x} - w := new(primeFieldElement) - - for n := 0; n < b.N; n++ { - w.Mul(z, z) - } -} - -// --- field operation functions - -func BenchmarkFp751Multiply(b *testing.B) { - for n := 0; n < b.N; n++ { - fp751Mul(&benchmarkFpElementX2, &bench_x, &bench_y) - } -} - -func BenchmarkFp751MontgomeryReduce(b *testing.B) { - z := bench_z - - // This benchmark actually computes garbage, because - // fp751MontgomeryReduce mangles its input, but since it's - // constant-time that shouldn't matter for the benchmarks. - for n := 0; n < b.N; n++ { - fp751MontgomeryReduce(&benchmarkFpElement, &z) - } -} - -func BenchmarkFp751AddReduced(b *testing.B) { - for n := 0; n < b.N; n++ { - fp751AddReduced(&benchmarkFpElement, &bench_x, &bench_y) - } -} - -func BenchmarkFp751SubReduced(b *testing.B) { - for n := 0; n < b.N; n++ { - fp751SubReduced(&benchmarkFpElement, &bench_x, &bench_y) - } -} - -func BenchmarkFp751ConditionalSwap(b *testing.B) { - x, y := bench_x, bench_y - for n := 0; n < b.N; n++ { - fp751ConditionalSwap(&x, &y, 1) - fp751ConditionalSwap(&x, &y, 0) - } -} - -func BenchmarkFp751StrongReduce(b *testing.B) { - x := bench_x - for n := 0; n < b.N; n++ { - fp751StrongReduce(&x) - } -} - -func BenchmarkFp751AddLazy(b *testing.B) { - var z FpElement - x, y := bench_x, bench_y - for n := 0; n < b.N; n++ { - fp751AddLazy(&z, &x, &y) - } -} - -func BenchmarkFp751X2AddLazy(b *testing.B) { - x, y, z := bench_z, bench_z, bench_z - for n := 0; n < b.N; n++ { - fp751X2AddLazy(&x, &y, &z) - } -} - -func BenchmarkFp751X2SubLazy(b *testing.B) { - x, y, z := bench_z, bench_z, bench_z - for n := 0; n < b.N; n++ { - fp751X2SubLazy(&x, &y, &z) - } -} diff --git a/dh/sidh/p751/consts.go b/dh/sidh/p751/consts.go deleted file mode 100644 index 8273727..0000000 --- a/dh/sidh/p751/consts.go +++ /dev/null @@ -1,227 +0,0 @@ -package p751 - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - cpu "github.com/henrydcase/nobs/utils" -) - -const ( - // SIDH public key byte size - P751_PublicKeySize = 564 - // SIDH shared secret byte size. - P751_SharedSecretSize = 188 - // Max size of secret key for 2-torsion group, corresponds to 2^e2 - P751_SecretBitLenA = 372 - // Size of secret key for 3-torsion group, corresponds to floor(log_2(3^e3)) - P751_SecretBitLenB = 378 - // P751 bytelen ceil(751/8) - P751_Bytelen = 94 - // Size of a compuatation strategy for 2-torsion group - strategySizeA = 185 - // Size of a compuatation strategy for 3-torsion group - strategySizeB = 238 - // Number of 64-bit limbs used to store Fp element - NumWords = 12 -) - -// CPU Capabilities. Those flags are referred by assembly code. According to -// https://github.com/golang/go/issues/28230, variables referred from the -// assembly must be in the same package. -// We declare them variables not constants in order to facilitate testing. -var ( - // Signals support for MULX which is in BMI2 - HasBMI2 = cpu.X86.HasBMI2 - // Signals support for ADX and BMI2 - HasADXandBMI2 = cpu.X86.HasBMI2 && cpu.X86.HasADX -) - -// The x-coordinate of PA -var P751_affine_PA = Fp2Element{ - A: FpElement{ - 0xC2FC08CEAB50AD8B, 0x1D7D710F55E457B1, 0xE8738D92953DCD6E, - 0xBAA7EBEE8A3418AA, 0xC9A288345F03F46F, 0xC8D18D167CFE2616, - 0x02043761F6B1C045, 0xAA1975E13180E7E9, 0x9E13D3FDC6690DE6, - 0x3A024640A3A3BB4F, 0x4E5AD44E6ACBBDAE, 0x0000544BEB561DAD, - }, - B: FpElement{ - 0xE6CC41D21582E411, 0x07C2ECB7C5DF400A, 0xE8E34B521432AEC4, - 0x50761E2AB085167D, 0x032CFBCAA6094B3C, 0x6C522F5FDF9DDD71, - 0x1319217DC3A1887D, 0xDC4FB25803353A86, 0x362C8D7B63A6AB09, - 0x39DCDFBCE47EA488, 0x4C27C99A2C28D409, 0x00003CB0075527C4, - }, -} - -// The x-coordinate of QA -var P751_affine_QA = Fp2Element{ - A: FpElement{ - 0xD56FE52627914862, 0x1FAD60DC96B5BAEA, 0x01E137D0BF07AB91, - 0x404D3E9252161964, 0x3C5385E4CD09A337, 0x4476426769E4AF73, - 0x9790C6DB989DFE33, 0xE06E1C04D2AA8B5E, 0x38C08185EDEA73B9, - 0xAA41F678A4396CA6, 0x92B9259B2229E9A0, 0x00002F9326818BE0, - }, - B: FpElement{ - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - }, -} - -// The x-coordinate of RA = PA-QA -var P751_affine_RA = Fp2Element{ - A: FpElement{ - 0x0BB84441DFFD19B3, 0x84B4DEA99B48C18E, 0x692DE648AD313805, - 0xE6D72761B6DFAEE0, 0x223975C672C3058D, 0xA0FDE0C3CBA26FDC, - 0xA5326132A922A3CA, 0xCA5E7F5D5EA96FA4, 0x127C7EFE33FFA8C6, - 0x4749B1567E2A23C4, 0x2B7DF5B4AF413BFA, 0x0000656595B9623C, - }, - B: FpElement{ - 0xED78C17F1EC71BE8, 0xF824D6DF753859B1, 0x33A10839B2A8529F, - 0xFC03E9E25FDEA796, 0xC4708A8054DF1762, 0x4034F2EC034C6467, - 0xABFB70FBF06ECC79, 0xDABE96636EC108B7, 0x49CBCFB090605FD3, - 0x20B89711819A45A7, 0xFB8E1590B2B0F63E, 0x0000556A5F964AB2, - }, -} - -// The x-coordinate of PB -var P751_affine_PB = Fp2Element{ - A: FpElement{ - 0xCFB6D71EF867AB0B, 0x4A5FDD76E9A45C76, 0x38B1EE69194B1F03, - 0xF6E7B18A7761F3F0, 0xFCF01A486A52C84C, 0xCBE2F63F5AA75466, - 0x6487BCE837B5E4D6, 0x7747F5A8C622E9B8, 0x4CBFE1E4EE6AEBBA, - 0x8A8616A13FA91512, 0x53DB980E1579E0A5, 0x000058FEBFF3BE69, - }, - B: FpElement{ - 0xA492034E7C075CC3, 0x677BAF00B04AA430, 0x3AAE0C9A755C94C8, - 0x1DC4B064E9EBB08B, 0x3684EDD04E826C66, 0x9BAA6CB661F01B22, - 0x20285A00AD2EFE35, 0xDCE95ABD0497065F, 0x16C7FBB3778E3794, - 0x26B3AC29CEF25AAF, 0xFB3C28A31A30AC1D, 0x000046ED190624EE, - }, -} - -// The x-coordinate of QB -var P751_affine_QB = Fp2Element{ - A: FpElement{ - 0xF1A8C9ED7B96C4AB, 0x299429DA5178486E, 0xEF4926F20CD5C2F4, - 0x683B2E2858B4716A, 0xDDA2FBCC3CAC3EEB, 0xEC055F9F3A600460, - 0xD5A5A17A58C3848B, 0x4652D836F42EAED5, 0x2F2E71ED78B3A3B3, - 0xA771C057180ADD1D, 0xC780A5D2D835F512, 0x0000114EA3B55AC1, - }, - B: FpElement{ - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - }, -} - -// The x-coordinate of RB = PB - QB -var P751_affine_RB = Fp2Element{ - A: FpElement{ - 0x1C0D6733769D0F31, 0xF084C3086E2659D1, 0xE23D5DA27BCBD133, - 0xF38EC9A8D5864025, 0x6426DC781B3B645B, 0x4B24E8E3C9FB03EE, - 0x6432792F9D2CEA30, 0x7CC8E8B1AE76E857, 0x7F32BFB626BB8963, - 0xB9F05995B48D7B74, 0x4D71200A7D67E042, 0x0000228457AF0637, - }, - B: FpElement{ - 0x4AE37E7D8F72BD95, 0xDD2D504B3E993488, 0x5D14E7FA1ECB3C3E, - 0x127610CEB75D6350, 0x255B4B4CAC446B11, 0x9EA12336C1F70CAF, - 0x79FA68A2147BC2F8, 0x11E895CFDADBBC49, 0xE4B9D3C4D6356C18, - 0x44B25856A67F951C, 0x5851541F61308D0B, 0x00002FFD994F7E4C, - }, -} - -// 2-torsion group computation strategy -var P751_AliceIsogenyStrategy = [strategySizeA]uint32{ - 0x50, 0x30, 0x1B, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, - 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x07, - 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, 0x02, 0x01, - 0x01, 0x01, 0x01, 0x0C, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02, - 0x01, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x05, 0x03, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x15, - 0x0C, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x05, 0x03, 0x02, 0x01, 0x01, - 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x09, 0x05, 0x03, 0x02, - 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, - 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x21, 0x14, 0x0C, 0x07, - 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, 0x02, 0x01, - 0x01, 0x01, 0x01, 0x05, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x08, 0x05, 0x03, 0x02, 0x01, 0x01, - 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, - 0x01, 0x01, 0x02, 0x01, 0x01} - -// 3-torsion group computation strategy -var P751_BobIsogenyStrategy = [strategySizeB]uint32{ - 0x70, 0x3F, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, - 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, - 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, - 0x01, 0x02, 0x01, 0x01, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, - 0x01, 0x01, 0x02, 0x01, 0x01, 0x1F, 0x10, 0x08, 0x04, 0x02, - 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, - 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x0F, 0x08, 0x04, - 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, - 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x31, 0x1F, 0x10, - 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, - 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x0F, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, - 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x07, 0x04, 0x02, 0x01, - 0x01, 0x02, 0x01, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x15, 0x0C, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x05, 0x03, 0x02, - 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x09, 0x05, - 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01} - -// Used internally by this package. Not consts as Go doesn't allow arrays to be consts -// ------------------------------- - -// p751 -var p751 = FpElement{ - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xeeafffffffffffff, - 0xe3ec968549f878a8, 0xda959b1a13f7cc76, 0x084e9867d6ebe876, - 0x8562b5045cb25748, 0x0e12909f97badc66, 0x00006fe5d541f71c} - -// 2*p751 -var p751x2 = FpElement{ - 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xDD5FFFFFFFFFFFFF, - 0xC7D92D0A93F0F151, 0xB52B363427EF98ED, 0x109D30CFADD7D0ED, - 0x0AC56A08B964AE90, 0x1C25213F2F75B8CD, 0x0000DFCBAA83EE38} - -// p751 + 1 -var p751p1 = FpElement{ - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0xeeb0000000000000, - 0xe3ec968549f878a8, 0xda959b1a13f7cc76, 0x084e9867d6ebe876, - 0x8562b5045cb25748, 0x0e12909f97badc66, 0x00006fe5d541f71c} - -// R^2 = (2^768)^2 mod p -var p751R2 = FpElement{ - 2535603850726686808, 15780896088201250090, 6788776303855402382, - 17585428585582356230, 5274503137951975249, 2266259624764636289, - 11695651972693921304, 13072885652150159301, 4908312795585420432, - 6229583484603254826, 488927695601805643, 72213483953973} - -// 1*R mod p -var P751OneFp2 = Fp2Element{ - A: FpElement{ - 0x249ad, 0x0, 0x0, 0x0, 0x0, 0x8310000000000000, 0x5527b1e4375c6c66, 0x697797bf3f4f24d0, 0xc89db7b2ac5c4e2e, 0x4ca4b439d2076956, 0x10f7926c7512c7e9, 0x2d5b24bce5e2}, -} - -// 1/2 * R mod p -var P751HalfFp2 = Fp2Element{ - A: FpElement{ - 0x00000000000124D6, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0xB8E0000000000000, - 0x9C8A2434C0AA7287, 0xA206996CA9A378A3, 0x6876280D41A41B52, - 0xE903B49F175CE04F, 0x0F8511860666D227, 0x00004EA07CFF6E7F}, -} diff --git a/dh/sidh/p751/curve_test.go b/dh/sidh/p751/curve_test.go deleted file mode 100644 index 0058b00..0000000 --- a/dh/sidh/p751/curve_test.go +++ /dev/null @@ -1,192 +0,0 @@ -package p751 - -import ( - "bytes" - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - "testing" - "testing/quick" -) - -func TestOne(t *testing.T) { - var tmp Fp2Element - - kFieldOps.Mul(&tmp, &P751OneFp2, &affine_xP) - if !VartimeEqFp2(&tmp, &affine_xP) { - t.Error("Not equal 1") - } -} - -// This test is here only to ensure that ScalarMult helper works correctly -func TestScalarMultVersusSage(t *testing.T) { - var xP ProjectivePoint - - xP = ProjectivePoint{X: affine_xP, Z: P751OneFp2} - xP = ScalarMult(&curve, &xP, mScalarBytes[:]) // = x([m]P) - affine_xQ := xP.ToAffine(kCurveOps) - if !VartimeEqFp2(&affine_xaP, affine_xQ) { - t.Error("\nExpected\n", affine_xaP, "\nfound\n", affine_xQ) - } -} - -func Test_jInvariant(t *testing.T) { - var curve = ProjectiveCurveParameters{A: curve_A, C: curve_C} - var jbufRes [P751_SharedSecretSize]byte - var jbufExp [P751_SharedSecretSize]byte - // Computed using Sage - // j = 3674553797500778604587777859668542828244523188705960771798425843588160903687122861541242595678107095655647237100722594066610650373491179241544334443939077738732728884873568393760629500307797547379838602108296735640313894560419*i + 3127495302417548295242630557836520229396092255080675419212556702820583041296798857582303163183558315662015469648040494128968509467224910895884358424271180055990446576645240058960358037224785786494172548090318531038910933793845 - var known_j = Fp2Element{ - A: FpElement{0xc7a8921c1fb23993, 0xa20aea321327620b, 0xf1caa17ed9676fa8, 0x61b780e6b1a04037, 0x47784af4c24acc7a, 0x83926e2e300b9adf, 0xcd891d56fae5b66, 0x49b66985beb733bc, 0xd4bcd2a473d518f, 0xe242239991abe224, 0xa8af5b20f98672f8, 0x139e4d4e4d98}, - B: FpElement{0xb5b52a21f81f359, 0x715e3a865db6d920, 0x9bac2f9d8911978b, 0xef14acd8ac4c1e3d, 0xe81aacd90cfb09c8, 0xaf898288de4a09d9, 0xb85a7fb88c5c4601, 0x2c37c3f1dd303387, 0x7ad3277fe332367c, 0xd4cbee7f25a8e6f8, 0x36eacbe979eaeffa, 0x59eb5a13ac33}, - } - kCurveOps.Jinvariant(&curve, jbufRes[:]) - kCurveOps.Fp2ToBytes(jbufExp[:], &known_j) - - if !bytes.Equal(jbufRes[:], jbufExp[:]) { - t.Error("Computed incorrect j-invariant: found\n", jbufRes, "\nexpected\n", jbufExp) - } -} - -func TestProjectivePointVartimeEq(t *testing.T) { - var xP ProjectivePoint - - xP = ProjectivePoint{X: affine_xP, Z: P751OneFp2} - xQ := xP - // Scale xQ, which results in the same projective point - kFieldOps.Mul(&xQ.X, &xQ.X, &curve_A) - kFieldOps.Mul(&xQ.Z, &xQ.Z, &curve_A) - if !VartimeEqProjFp2(&xP, &xQ) { - t.Error("Expected the scaled point to be equal to the original") - } -} - -func TestPointDoubleVersusSage(t *testing.T) { - var curve = ProjectiveCurveParameters{A: curve_A, C: curve_C} - var params = kCurveOps.CalcCurveParamsEquiv4(&curve) - var xP ProjectivePoint - - xP = ProjectivePoint{X: affine_xP, Z: P751OneFp2} - kCurveOps.Pow2k(&xP, ¶ms, 1) - affine_xQ := xP.ToAffine(kCurveOps) - if !VartimeEqFp2(affine_xQ, &affine_xP2) { - t.Error("\nExpected\n", affine_xP2, "\nfound\n", affine_xQ) - } -} - -func TestPointMul4VersusSage(t *testing.T) { - var params = kCurveOps.CalcCurveParamsEquiv4(&curve) - var xP ProjectivePoint - - xP = ProjectivePoint{X: affine_xP, Z: P751OneFp2} - kCurveOps.Pow2k(&xP, ¶ms, 2) - affine_xQ := xP.ToAffine(kCurveOps) - if !VartimeEqFp2(affine_xQ, &affine_xP4) { - t.Error("\nExpected\n", affine_xP4, "\nfound\n", affine_xQ) - } -} - -func TestPointMul9VersusSage(t *testing.T) { - var params = kCurveOps.CalcCurveParamsEquiv3(&curve) - var xP ProjectivePoint - - xP = ProjectivePoint{X: affine_xP, Z: P751OneFp2} - kCurveOps.Pow3k(&xP, ¶ms, 2) - affine_xQ := xP.ToAffine(kCurveOps) - if !VartimeEqFp2(affine_xQ, &affine_xP9) { - t.Error("\nExpected\n", affine_xP9, "\nfound\n", affine_xQ) - } -} - -func TestPointPow2kVersusScalarMult(t *testing.T) { - var xP, xQ, xR ProjectivePoint - var params = kCurveOps.CalcCurveParamsEquiv4(&curve) - - xP = ProjectivePoint{X: affine_xP, Z: P751OneFp2} - xQ = xP - kCurveOps.Pow2k(&xQ, ¶ms, 5) - xR = ScalarMult(&curve, &xP, []byte{32}) - affine_xQ := xQ.ToAffine(kCurveOps) // = x([32]P) - affine_xR := xR.ToAffine(kCurveOps) // = x([32]P) - - if !VartimeEqFp2(affine_xQ, affine_xR) { - t.Error("\nExpected\n", affine_xQ, "\nfound\n", affine_xR) - } -} - -func TestRecoverCoordinateA(t *testing.T) { - var cparam ProjectiveCurveParameters - // Vectors generated with SIKE reference implementation - var a = Fp2Element{ - A: FpElement{0x9331D9C5AAF59EA4, 0xB32B702BE4046931, 0xCEBB333912ED4D34, 0x5628CE37CD29C7A2, 0x0BEAC5ED48B7F58E, 0x1FB9D3E281D65B07, 0x9C0CFACC1E195662, 0xAE4BCE0F6B70F7D9, 0x59E4E63D43FE71A0, 0xEF7CE57560CC8615, 0xE44A8FB7901E74E8, 0x000069D13C8366D1}, - B: FpElement{0xF6DA1070279AB966, 0xA78FB0CE7268C762, 0x19B40F044A57ABFA, 0x7AC8EE6160C0C233, 0x93D4993442947072, 0x757D2B3FA4E44860, 0x073A920F8C4D5257, 0x2031F1B054734037, 0xDEFAA1D2406555CD, 0x26F9C70E1496BE3D, 0x5B3F335A0A4D0976, 0x000013628B2E9C59}} - var affine_xP = Fp2Element{ - A: FpElement{0xea6b2d1e2aebb250, 0x35d0b205dc4f6386, 0xb198e93cb1830b8d, 0x3b5b456b496ddcc6, 0x5be3f0d41132c260, 0xce5f188807516a00, 0x54f3e7469ea8866d, 0x33809ef47f36286, 0x6fa45f83eabe1edb, 0x1b3391ae5d19fd86, 0x1e66daf48584af3f, 0xb430c14aaa87}, - B: FpElement{0x97b41ebc61dcb2ad, 0x80ead31cb932f641, 0x40a940099948b642, 0x2a22fd16cdc7fe84, 0xaabf35b17579667f, 0x76c1d0139feb4032, 0x71467e1e7b1949be, 0x678ca8dadd0d6d81, 0x14445daea9064c66, 0x92d161eab4fa4691, 0x8dfbb01b6b238d36, 0x2e3718434e4e}} - var affine_xQ = Fp2Element{ - A: FpElement{0xb055cf0ca1943439, 0xa9ff5de2fa6c69ed, 0x4f2761f934e5730a, 0x61a1dcaa1f94aa4b, 0xce3c8fadfd058543, 0xeac432aaa6701b8e, 0x8491d523093aea8b, 0xba273f9bd92b9b7f, 0xd8f59fd34439bb5a, 0xdc0350261c1fe600, 0x99375ab1eb151311, 0x14d175bbdbc5}, - B: FpElement{0xffb0ef8c2111a107, 0x55ceca3825991829, 0xdbf8a1ccc075d34b, 0xb8e9187bd85d8494, 0x670aa2d5c34a03b0, 0xef9fe2ed2b064953, 0xc911f5311d645aee, 0xf4411f409e410507, 0x934a0a852d03e1a8, 0xe6274e67ae1ad544, 0x9f4bc563c69a87bc, 0x6f316019681e}} - var affine_xQmP = Fp2Element{ - A: FpElement{0x6ffb44306a153779, 0xc0ffef21f2f918f3, 0x196c46d35d77f778, 0x4a73f80452edcfe6, 0x9b00836bce61c67f, 0x387879418d84219e, 0x20700cf9fc1ec5d1, 0x1dfe2356ec64155e, 0xf8b9e33038256b1c, 0xd2aaf2e14bada0f0, 0xb33b226e79a4e313, 0x6be576fad4e5}, - B: FpElement{0x7db5dbc88e00de34, 0x75cc8cb9f8b6e11e, 0x8c8001c04ebc52ac, 0x67ef6c981a0b5a94, 0xc3654fbe73230738, 0xc6a46ee82983ceca, 0xed1aa61a27ef49f0, 0x17fe5a13b0858fe0, 0x9ae0ca945a4c6b3c, 0x234104a218ad8878, 0xa619627166104394, 0x556a01ff2e7e}} - - cparam.C = P751OneFp2 - kCurveOps.RecoverCoordinateA(&cparam, &affine_xP, &affine_xQ, &affine_xQmP) - - // Check A is correct - if !VartimeEqFp2(&cparam.A, &a) { - t.Error("\nExpected\n", a, "\nfound\n", cparam.A) - } - - // Check C is not changed - if !VartimeEqFp2(&cparam.C, &P751OneFp2) { - t.Error("\nExpected\n", cparam.C, "\nfound\n", P751OneFp2) - } -} - -func TestR2LVersusSage(t *testing.T) { - var xR ProjectivePoint - - sageAffine_xR := Fp2Element{ - A: FpElement{0x729465ba800d4fd5, 0x9398015b59e514a1, 0x1a59dd6be76c748e, 0x1a7db94eb28dd55c, 0x444686e680b1b8ec, 0xcc3d4ace2a2454ff, 0x51d3dab4ec95a419, 0xc3b0f33594acac6a, 0x9598a74e7fd44f8a, 0x4fbf8c638f1c2e37, 0x844e347033052f51, 0x6cd6de3eafcf}, - B: FpElement{0x85da145412d73430, 0xd83c0e3b66eb3232, 0xd08ff2d453ec1369, 0xa64aaacfdb395b13, 0xe9cba211a20e806e, 0xa4f80b175d937cfc, 0x556ce5c64b1f7937, 0xb59b39ea2b3fdf7a, 0xc2526b869a4196b3, 0x8dad90bca9371750, 0xdfb4a30c9d9147a2, 0x346d2130629b}} - xR = kCurveOps.ScalarMul3Pt(&curve, &threePointLadderInputs[0], &threePointLadderInputs[1], &threePointLadderInputs[2], uint(len(mScalarBytes)*8), mScalarBytes[:]) - affine_xR := xR.ToAffine(kCurveOps) - - if !VartimeEqFp2(affine_xR, &sageAffine_xR) { - t.Error("\nExpected\n", sageAffine_xR, "\nfound\n", affine_xR) - } -} - -func TestPointTripleVersusAddDouble(t *testing.T) { - tripleEqualsAddDouble := func(params GeneratedTestParams) bool { - var P2, P3, P2plusP ProjectivePoint - - eqivParams4 := kCurveOps.CalcCurveParamsEquiv4(¶ms.Cparam) - eqivParams3 := kCurveOps.CalcCurveParamsEquiv3(¶ms.Cparam) - P2 = params.Point - P3 = params.Point - kCurveOps.Pow2k(&P2, &eqivParams4, 1) // = x([2]P) - kCurveOps.Pow3k(&P3, &eqivParams3, 1) // = x([3]P) - P2plusP = AddProjFp2(&P2, ¶ms.Point, ¶ms.Point) // = x([2]P + P) - return VartimeEqProjFp2(&P3, &P2plusP) - } - - if err := quick.Check(tripleEqualsAddDouble, quickCheckConfig); err != nil { - t.Error(err) - } -} - -func BenchmarkThreePointLadder379BitScalar(b *testing.B) { - var mScalarBytes = [...]uint8{84, 222, 146, 63, 85, 18, 173, 162, 167, 38, 10, 8, 143, 176, 93, 228, 247, 128, 50, 128, 205, 42, 15, 137, 119, 67, 43, 3, 61, 91, 237, 24, 235, 12, 53, 96, 186, 164, 232, 223, 197, 224, 64, 109, 137, 63, 246, 4} - - for n := 0; n < b.N; n++ { - kCurveOps.ScalarMul3Pt(&curve, &threePointLadderInputs[0], &threePointLadderInputs[1], &threePointLadderInputs[2], uint(len(mScalarBytes)*8), mScalarBytes[:]) - } -} - -func BenchmarkR2L379BitScalar(b *testing.B) { - var mScalarBytes = [...]uint8{84, 222, 146, 63, 85, 18, 173, 162, 167, 38, 10, 8, 143, 176, 93, 228, 247, 128, 50, 128, 205, 42, 15, 137, 119, 67, 43, 3, 61, 91, 237, 24, 235, 12, 53, 96, 186, 164, 232, 223, 197, 224, 64, 109, 137, 63, 246, 4} - - for n := 0; n < b.N; n++ { - kCurveOps.ScalarMul3Pt(&curve, &threePointLadderInputs[0], &threePointLadderInputs[1], &threePointLadderInputs[2], uint(len(mScalarBytes)*8), mScalarBytes[:]) - } -} diff --git a/dh/sidh/p751/field_ops.go b/dh/sidh/p751/field_ops.go deleted file mode 100644 index cc208fb..0000000 --- a/dh/sidh/p751/field_ops.go +++ /dev/null @@ -1,253 +0,0 @@ -package p751 - -import . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - -// 2*p751 - -//------------------------------------------------------------------------------ -// Implementtaion of FieldOperations -//------------------------------------------------------------------------------ - -// Implements FieldOps -type fp751Ops struct{} - -func FieldOperations() FieldOps { - return fp751Ops{} -} - -func (fp751Ops) Add(dest, lhs, rhs *Fp2Element) { - fp751AddReduced(&dest.A, &lhs.A, &rhs.A) - fp751AddReduced(&dest.B, &lhs.B, &rhs.B) -} - -func (fp751Ops) Sub(dest, lhs, rhs *Fp2Element) { - fp751SubReduced(&dest.A, &lhs.A, &rhs.A) - fp751SubReduced(&dest.B, &lhs.B, &rhs.B) -} - -func (fp751Ops) Mul(dest, lhs, rhs *Fp2Element) { - // Let (a,b,c,d) = (lhs.a,lhs.b,rhs.a,rhs.b). - a := &lhs.A - b := &lhs.B - c := &rhs.A - d := &rhs.B - - // We want to compute - // - // (a + bi)*(c + di) = (a*c - b*d) + (a*d + b*c)i - // - // Use Karatsuba's trick: note that - // - // (b - a)*(c - d) = (b*c + a*d) - a*c - b*d - // - // so (a*d + b*c) = (b-a)*(c-d) + a*c + b*d. - - var ac, bd FpElementX2 - fp751Mul(&ac, a, c) // = a*c*R*R - fp751Mul(&bd, b, d) // = b*d*R*R - - var b_minus_a, c_minus_d FpElement - fp751SubReduced(&b_minus_a, b, a) // = (b-a)*R - fp751SubReduced(&c_minus_d, c, d) // = (c-d)*R - - var ad_plus_bc FpElementX2 - fp751Mul(&ad_plus_bc, &b_minus_a, &c_minus_d) // = (b-a)*(c-d)*R*R - fp751X2AddLazy(&ad_plus_bc, &ad_plus_bc, &ac) // = ((b-a)*(c-d) + a*c)*R*R - fp751X2AddLazy(&ad_plus_bc, &ad_plus_bc, &bd) // = ((b-a)*(c-d) + a*c + b*d)*R*R - - fp751MontgomeryReduce(&dest.B, &ad_plus_bc) // = (a*d + b*c)*R mod p - - var ac_minus_bd FpElementX2 - fp751X2SubLazy(&ac_minus_bd, &ac, &bd) // = (a*c - b*d)*R*R - fp751MontgomeryReduce(&dest.A, &ac_minus_bd) // = (a*c - b*d)*R mod p -} - -func (fp751Ops) Square(dest, x *Fp2Element) { - a := &x.A - b := &x.B - - // We want to compute - // - // (a + bi)*(a + bi) = (a^2 - b^2) + 2abi. - - var a2, a_plus_b, a_minus_b FpElement - fp751AddReduced(&a2, a, a) // = a*R + a*R = 2*a*R - fp751AddReduced(&a_plus_b, a, b) // = a*R + b*R = (a+b)*R - fp751SubReduced(&a_minus_b, a, b) // = a*R - b*R = (a-b)*R - - var asq_minus_bsq, ab2 FpElementX2 - fp751Mul(&asq_minus_bsq, &a_plus_b, &a_minus_b) // = (a+b)*(a-b)*R*R = (a^2 - b^2)*R*R - fp751Mul(&ab2, &a2, b) // = 2*a*b*R*R - - fp751MontgomeryReduce(&dest.A, &asq_minus_bsq) // = (a^2 - b^2)*R mod p - fp751MontgomeryReduce(&dest.B, &ab2) // = 2*a*b*R mod p -} - -// Set dest = 1/x -// -// Allowed to overlap dest with x. -// -// Returns dest to allow chaining operations. -func (fp751Ops) Inv(dest, x *Fp2Element) { - a := &x.A - b := &x.B - - // We want to compute - // - // 1 1 (a - bi) (a - bi) - // -------- = -------- -------- = ----------- - // (a + bi) (a + bi) (a - bi) (a^2 + b^2) - // - // Letting c = 1/(a^2 + b^2), this is - // - // 1/(a+bi) = a*c - b*ci. - - var asq_plus_bsq primeFieldElement - var asq, bsq FpElementX2 - fp751Mul(&asq, a, a) // = a*a*R*R - fp751Mul(&bsq, b, b) // = b*b*R*R - fp751X2AddLazy(&asq, &asq, &bsq) // = (a^2 + b^2)*R*R - fp751MontgomeryReduce(&asq_plus_bsq.A, &asq) // = (a^2 + b^2)*R mod p - // Now asq_plus_bsq = a^2 + b^2 - - // Invert asq_plus_bsq - inv := asq_plus_bsq - inv.Mul(&asq_plus_bsq, &asq_plus_bsq) - inv.P34(&inv) - inv.Mul(&inv, &inv) - inv.Mul(&inv, &asq_plus_bsq) - - var ac FpElementX2 - fp751Mul(&ac, a, &inv.A) - fp751MontgomeryReduce(&dest.A, &ac) - - var minus_b FpElement - fp751SubReduced(&minus_b, &minus_b, b) - var minus_bc FpElementX2 - fp751Mul(&minus_bc, &minus_b, &inv.A) - fp751MontgomeryReduce(&dest.B, &minus_bc) -} - -// In case choice == 1, performs following swap in constant time: -// xPx <-> xQx -// xPz <-> xQz -// Otherwise returns xPx, xPz, xQx, xQz unchanged -func (fp751Ops) CondSwap(xPx, xPz, xQx, xQz *Fp2Element, choice uint8) { - fp751ConditionalSwap(&xPx.A, &xQx.A, choice) - fp751ConditionalSwap(&xPx.B, &xQx.B, choice) - fp751ConditionalSwap(&xPz.A, &xQz.A, choice) - fp751ConditionalSwap(&xPz.B, &xQz.B, choice) -} - -// Converts values in x.A and x.B to Montgomery domain -// x.A = x.A * R mod p -// x.B = x.B * R mod p -func (fp751Ops) ToMontgomery(x *Fp2Element) { - var aRR FpElementX2 - - // convert to montgomery domain - fp751Mul(&aRR, &x.A, &p751R2) // = a*R*R - fp751MontgomeryReduce(&x.A, &aRR) // = a*R mod p - fp751Mul(&aRR, &x.B, &p751R2) - fp751MontgomeryReduce(&x.B, &aRR) -} - -// Converts values in x.A and x.B from Montgomery domain -// a = x.A mod p -// b = x.B mod p -// -// After returning from the call x is not modified. -func (fp751Ops) FromMontgomery(x *Fp2Element, out *Fp2Element) { - var aR FpElementX2 - - // convert from montgomery domain - copy(aR[:], x.A[:]) - fp751MontgomeryReduce(&out.A, &aR) // = a mod p in [0, 2p) - fp751StrongReduce(&out.A) // = a mod p in [0, p) - for i := range aR { - aR[i] = 0 - } - copy(aR[:], x.B[:]) - fp751MontgomeryReduce(&out.B, &aR) - fp751StrongReduce(&out.B) -} - -//------------------------------------------------------------------------------ -// Prime Field -//------------------------------------------------------------------------------ - -// Represents an element of the prime field F_p in Montgomery domain -type primeFieldElement struct { - // The value `A`is represented by `aR mod p`. - A FpElement -} - -// Set dest = lhs * rhs. -// -// Allowed to overlap lhs or rhs with dest. -// -// Returns dest to allow chaining operations. -func (dest *primeFieldElement) Mul(lhs, rhs *primeFieldElement) *primeFieldElement { - a := &lhs.A // = a*R - b := &rhs.A // = b*R - - var ab FpElementX2 - fp751Mul(&ab, a, b) // = a*b*R*R - fp751MontgomeryReduce(&dest.A, &ab) // = a*b*R mod p - - return dest -} - -// Set dest = x^(2^k), for k >= 1, by repeated squarings. -// -// Allowed to overlap x with dest. -// -// Returns dest to allow chaining operations. -func (dest *primeFieldElement) Pow2k(x *primeFieldElement, k uint8) *primeFieldElement { - dest.Mul(x, x) - for i := uint8(1); i < k; i++ { - dest.Mul(dest, dest) - } - - return dest -} - -// Set dest = x^((p-3)/4). If x is square, this is 1/sqrt(x). -// -// Allowed to overlap x with dest. -// -// Returns dest to allow chaining operations. -func (dest *primeFieldElement) P34(x *primeFieldElement) *primeFieldElement { - // Sliding-window strategy computed with Sage, awk, sed, and tr. - // - // This performs sum(powStrategy) = 744 squarings and len(mulStrategy) - // = 137 multiplications, in addition to 1 squaring and 15 - // multiplications to build a lookup table. - // - // In total this is 745 squarings, 152 multiplications. Since squaring - // is not implemented for the prime field, this is 897 multiplications - // in total. - powStrategy := [137]uint8{5, 7, 6, 2, 10, 4, 6, 9, 8, 5, 9, 4, 7, 5, 5, 4, 8, 3, 9, 5, 5, 4, 10, 4, 6, 6, 6, 5, 8, 9, 3, 4, 9, 4, 5, 6, 6, 2, 9, 4, 5, 5, 5, 7, 7, 9, 4, 6, 4, 8, 5, 8, 6, 6, 2, 9, 7, 4, 8, 8, 8, 4, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2} - mulStrategy := [137]uint8{31, 23, 21, 1, 31, 7, 7, 7, 9, 9, 19, 15, 23, 23, 11, 7, 25, 5, 21, 17, 11, 5, 17, 7, 11, 9, 23, 9, 1, 19, 5, 3, 25, 15, 11, 29, 31, 1, 29, 11, 13, 9, 11, 27, 13, 19, 15, 31, 3, 29, 23, 31, 25, 11, 1, 21, 19, 15, 15, 21, 29, 13, 23, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 3} - initialMul := uint8(27) - - // Build a lookup table of odd multiples of x. - lookup := [16]primeFieldElement{} - xx := &primeFieldElement{} - xx.Mul(x, x) // Set xx = x^2 - lookup[0] = *x - for i := 1; i < 16; i++ { - lookup[i].Mul(&lookup[i-1], xx) - } - // Now lookup = {x, x^3, x^5, ... } - // so that lookup[i] = x^{2*i + 1} - // so that lookup[k/2] = x^k, for odd k - - *dest = lookup[initialMul/2] - for i := uint8(0); i < 137; i++ { - dest.Pow2k(dest, powStrategy[i]) - dest.Mul(dest, &lookup[mulStrategy[i]/2]) - } - - return dest -} diff --git a/dh/sidh/p751/isogeny_test.go b/dh/sidh/p751/isogeny_test.go deleted file mode 100644 index ef3b3e4..0000000 --- a/dh/sidh/p751/isogeny_test.go +++ /dev/null @@ -1,130 +0,0 @@ -package p751 - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - "testing" -) - -func TestFourIsogenyVersusSage(t *testing.T) { - var xR, xP4, resPhiXr, expPhiXr ProjectivePoint - var phi = Newisogeny4(kFieldOps) - - // TODO: The sage code needs to be aligned to SIDHv3 - // sage: p = 2^372 * 3^239 - 1; Fp = GF(p) - // sage: R. = Fp[] - // sage: Fp2 = Fp.extension(x^2 + 1, 'i') - // sage: i = Fp2.gen() - // sage: E0Fp = EllipticCurve(Fp, [0,0,0,1,0]) - // sage: E0Fp2 = EllipticCurve(Fp2, [0,0,0,1,0]) - // sage: x_PA = 11 - // sage: y_PA = -Fp(11^3 + 11).sqrt() - // sage: x_PB = 6 - // sage: y_PB = -Fp(6^3 + 6).sqrt() - // sage: P_A = 3^239 * E0Fp((x_PA,y_PA)) - // sage: P_B = 2^372 * E0Fp((x_PB,y_PB)) - // sage: def tau(P): - // ....: return E0Fp2( (-P.xy()[0], i*P.xy()[1])) - // ....: - // sage: m_B = 3*randint(0,3^238) - // sage: m_A = 2*randint(0,2^371) - // sage: R_A = E0Fp2(P_A) + m_A*tau(P_A) - // sage: def y_recover(x, a): - // ....: return (x**3 + a*x**2 + x).sqrt() - // ....: - // sage: first_4_torsion_point = E0Fp2(1, y_recover(Fp2(1),0)) - // sage: sage_first_4_isogeny = E0Fp2.isogeny(first_4_torsion_point) - // sage: a = Fp2(0) - // sage: E1A = EllipticCurve(Fp2, [0,(2*(a+6))/(a-2),0,1,0]) - // sage: sage_isomorphism = sage_first_4_isogeny.codomain().isomorphism_to(E1A) - // sage: isogenized_R_A = sage_isomorphism(sage_first_4_isogeny(R_A)) - // sage: P_4 = (2**(372-4))*isogenized_R_A - // sage: P_4._order = 4 #otherwise falls back to generic group methods for order - // sage: X4, Z4 = P_4.xy()[0], 1 - // sage: phi4 = EllipticCurveIsogeny(E1A, P_4, None, 4) - // sage: E2A_sage = phi4.codomain() # not in monty form - // sage: Aprime, Cprime = 2*(2*X4^4 - Z4^4), Z4^4 - // sage: E2A = EllipticCurve(Fp2, [0,Aprime/Cprime,0,1,0]) - // sage: sage_iso = E2A_sage.isomorphism_to(E2A) - // sage: isogenized2_R_A = sage_iso(phi4(isogenized_R_A)) - - xP4 = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x2afd75a913f3d5e7, 0x2918fba06f88c9ab, 0xa4ac4dc7cb526f05, 0x2d19e9391a607300, 0x7a79e2b34091b54, 0x3ad809dcb42f1792, 0xd46179328bd6402a, 0x1afa73541e2c4f3f, 0xf602d73ace9bdbd8, 0xd77ac58f6bab7004, 0x4689d97f6793b3b3, 0x4f26b00e42b7}, - B: FpElement{0x6cdf918dafdcb890, 0x666f273cc29cfae2, 0xad00fcd31ba618e2, 0x5fbcf62bef2f6a33, 0xf408bb88318e5098, 0x84ab97849453d175, 0x501bbfcdcfb8e1ac, 0xf2370098e6b5542c, 0xc7dc73f5f0f6bd32, 0xdd76dcd86729d1cf, 0xca22c905029996e4, 0x5cf4a9373de3}}, - Z: P751OneFp2} - xR = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0xff99e76f78da1e05, 0xdaa36bd2bb8d97c4, 0xb4328cee0a409daf, 0xc28b099980c5da3f, 0xf2d7cd15cfebb852, 0x1935103dded6cdef, 0xade81528de1429c3, 0x6775b0fa90a64319, 0x25f89817ee52485d, 0x706e2d00848e697, 0xc4958ec4216d65c0, 0xc519681417f}, - B: FpElement{0x742fe7dde60e1fb9, 0x801a3c78466a456b, 0xa9f945b786f48c35, 0x20ce89e1b144348f, 0xf633970b7776217e, 0x4c6077a9b38976e5, 0x34a513fc766c7825, 0xacccba359b9cd65, 0xd0ca8383f0fd0125, 0x77350437196287a, 0x9fe1ad7706d4ea21, 0x4d26129ee42d}}, - Z: P751OneFp2} - expPhiXr = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x111efd8bd0b7a01e, 0x6ab75a4f3789ca9b, 0x939dbe518564cac4, 0xf9eeaba1601d0434, 0x8d41f8ba6edac998, 0xfcd2557efe9aa170, 0xb3c3549c098b7844, 0x52874fef6f81127c, 0xb2b9ac82aa518bb3, 0xee70820230520a86, 0xd4012b7f5efb184a, 0x573e4536329b}, - B: FpElement{0xa99952281e932902, 0x569a89a571f2c7b1, 0x6150143846ba3f6b, 0x11fd204441e91430, 0x7f469bd55c9b07b, 0xb72db8b9de35b161, 0x455a9a37a940512a, 0xb0cff7670abaf906, 0x18c785b7583375fe, 0x603ab9ca403c9148, 0xab54ba3a6e6c62c1, 0x2726d7d57c4f}}, - Z: P751OneFp2} - - phi.GenerateCurve(&xP4) - resPhiXr = phi.EvaluatePoint(&xR) - if !VartimeEqProjFp2(&expPhiXr, &resPhiXr) { - t.Error("\nExpected\n", expPhiXr.ToAffine(kCurveOps), "\nfound\n", resPhiXr.ToAffine(kCurveOps)) - } -} - -func TestThreeIsogenyVersusSage(t *testing.T) { - var xR, xP3, resPhiXr, expPhiXr ProjectivePoint - var phi = Newisogeny3(kFieldOps) - - // sage: %colors Linux - // sage: p = 2^372 * 3^239 - 1; Fp = GF(p) - // sage: R. = Fp[] - // sage: Fp2 = Fp.extension(x^2 + 1, 'i') - // sage: i = Fp2.gen() - // sage: E0Fp = EllipticCurve(Fp, [0,0,0,1,0]) - // sage: E0Fp2 = EllipticCurve(Fp2, [0,0,0,1,0]) - // sage: x_PA = 11 - // sage: y_PA = -Fp(11^3 + 11).sqrt() - // sage: x_PB = 6 - // sage: y_PB = -Fp(6^3 + 6).sqrt() - // sage: P_A = 3^239 * E0Fp((x_PA,y_PA)) - // sage: P_B = 2^372 * E0Fp((x_PB,y_PB)) - // sage: def tau(P): - // ....: return E0Fp2( (-P.xy()[0], i*P.xy()[1])) - // ....: - // sage: m_B = 3*randint(0,3^238) - // sage: R_B = E0Fp2(P_B) + m_B*tau(P_B) - // sage: P_3 = (3^238)*R_B - // sage: def three_isog(P_3, P): - // ....: X3, Z3 = P_3.xy()[0], 1 - // ....: XP, ZP = P.xy()[0], 1 - // ....: x = (XP*(X3*XP - Z3*ZP)^2)/(ZP*(Z3*XP - X3*ZP)^2) - // ....: A3, C3 = (Z3^4 + 9*X3^2*(2*Z3^2 - 3*X3^2)), 4*X3*Z3^3 - // ....: cod = EllipticCurve(Fp2, [0,A3/C3,0,1,0]) - // ....: return cod.lift_x(x) - // ....: - // sage: isogenized_R_B = three_isog(P_3, R_B) - - xR = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0xbd0737ed5cc9a3d7, 0x45ae6d476517c101, 0x6f228e9e7364fdb2, 0xbba4871225b3dbd, 0x6299ccd2e5da1a07, 0x38488fe4af5f2d0e, 0xec23cae5a86e980c, 0x26c804ba3f1edffa, 0xfbbed81932df60e5, 0x7e00e9d182ae9187, 0xc7654abb66d05f4b, 0x262d0567237b}, - B: FpElement{0x3a3b5b6ad0b2ac33, 0x246602b5179127d3, 0x502ae0e9ad65077d, 0x10a3a37237e1bf70, 0x4a1ab9294dd05610, 0xb0f3adac30fe1fa6, 0x341995267faf70cb, 0xa14dd94d39cf4ec1, 0xce4b7527d1bf5568, 0xe0410423ed45c7e4, 0x38011809b6425686, 0x28f52472ebed}}, - Z: P751OneFp2} - - xP3 = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x7bb7a4a07b0788dc, 0xdc36a3f6607b21b0, 0x4750e18ee74cf2f0, 0x464e319d0b7ab806, 0xc25aa44c04f758ff, 0x392e8521a46e0a68, 0xfc4e76b63eff37df, 0x1f3566d892e67dd8, 0xf8d2eb0f73295e65, 0x457b13ebc470bccb, 0xfda1cc9efef5be33, 0x5dbf3d92cc02}, - B: FpElement{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, - Z: P751OneFp2} - - expPhiXr = ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x286db7d75913c5b1, 0xcb2049ad50189220, 0xccee90ef765fa9f4, 0x65e52ce2730e7d88, 0xa6b6b553bd0d06e7, 0xb561ecec14591590, 0x17b7a66d8c64d959, 0x77778cecbe1461e, 0x9405c9c0c41a57ce, 0x8f6b4847e8ca7d3d, 0xf625eb987b366937, 0x421b3590e345}, - B: FpElement{0x566b893803e7d8d6, 0xe8c71a04d527e696, 0x5a1d8f87bf5eb51, 0x42ae08ae098724f, 0x4ee3d7c7af40ca2e, 0xd9f9ab9067bb10a7, 0xecd53d69edd6328c, 0xa581e9202dea107d, 0x8bcdfb6c8ecf9257, 0xe7cbbc2e5cbcf2af, 0x5f031a8701f0e53e, 0x18312d93e3cb}}, - Z: P751OneFp2} - - phi.GenerateCurve(&xP3) - resPhiXr = phi.EvaluatePoint(&xR) - - if !VartimeEqProjFp2(&expPhiXr, &resPhiXr) { - t.Error("\nExpected\n", expPhiXr.ToAffine(kCurveOps), "\nfound\n", resPhiXr.ToAffine(kCurveOps)) - } -} diff --git a/dh/sidh/p751/utils_test.go b/dh/sidh/p751/utils_test.go deleted file mode 100644 index 7682c9c..0000000 --- a/dh/sidh/p751/utils_test.go +++ /dev/null @@ -1,340 +0,0 @@ -package p751 - -// Tools used for testing and debugging - -import ( - "fmt" - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - "math/big" - "math/rand" - "reflect" - "testing/quick" -) - -/* ------------------------------------------------------------------------- - Underlying field configuration - -------------------------------------------------------------------------*/ -var ( - kFieldOps = FieldOperations() - kParams = &SidhParams{ - Op: kFieldOps, - OneFp2: P751OneFp2, - HalfFp2: P751HalfFp2, - Bytelen: P751_Bytelen, - } - kCurveOps = &CurveOperations{Params: kParams} -) - -/* ------------------------------------------------------------------------- - Configure testing/quick - -------------------------------------------------------------------------*/ -var ( - quickCheckScaleFactor = uint8(3) - quickCheckConfig = &quick.Config{MaxCount: (1 << (12 + quickCheckScaleFactor))} -) - -/* ------------------------------------------------------------------------- - Structure used by tests - -------------------------------------------------------------------------*/ -type GeneratedTestParams struct { - Point ProjectivePoint - Cparam ProjectiveCurveParameters - ExtElem Fp2Element -} - -/* ------------------------------------------------------------------------- -Test values - -------------------------------------------------------------------------*/ - -// A = 4385300808024233870220415655826946795549183378139271271040522089756750951667981765872679172832050962894122367066234419550072004266298327417513857609747116903999863022476533671840646615759860564818837299058134292387429068536219*i + 1408083354499944307008104531475821995920666351413327060806684084512082259107262519686546161682384352696826343970108773343853651664489352092568012759783386151707999371397181344707721407830640876552312524779901115054295865393760 -var ( - curve_A = Fp2Element{ - A: FpElement{0x8319eb18ca2c435e, 0x3a93beae72cd0267, 0x5e465e1f72fd5a84, 0x8617fa4150aa7272, 0x887da24799d62a13, 0xb079b31b3c7667fe, 0xc4661b150fa14f2e, 0xd4d2b2967bc6efd6, 0x854215a8b7239003, 0x61c5302ccba656c2, 0xf93194a27d6f97a2, 0x1ed9532bca75}, - B: FpElement{0xb6f541040e8c7db6, 0x99403e7365342e15, 0x457e9cee7c29cced, 0x8ece72dc073b1d67, 0x6e73cef17ad28d28, 0x7aed836ca317472, 0x89e1de9454263b54, 0x745329277aa0071b, 0xf623dfc73bc86b9b, 0xb8e3c1d8a9245882, 0x6ad0b3d317770bec, 0x5b406e8d502b}} - - // C = 933177602672972392833143808100058748100491911694554386487433154761658932801917030685312352302083870852688835968069519091048283111836766101703759957146191882367397129269726925521881467635358356591977198680477382414690421049768*i + 9088894745865170214288643088620446862479558967886622582768682946704447519087179261631044546285104919696820250567182021319063155067584445633834024992188567423889559216759336548208016316396859149888322907914724065641454773776307 - curve_C = Fp2Element{ - A: FpElement{0x4fb2358bbf723107, 0x3a791521ac79e240, 0x283e24ef7c4c922f, 0xc89baa1205e33cc, 0x3031be81cff6fee1, 0xaf7a494a2f6a95c4, 0x248d251eaac83a1d, 0xc122fca1e2550c88, 0xbc0451b11b6cfd3d, 0x9c0a114ab046222c, 0x43b957b32f21f6ea, 0x5b9c87fa61de}, - B: FpElement{0xacf142afaac15ec6, 0xfd1322a504a071d5, 0x56bb205e10f6c5c6, 0xe204d2849a97b9bd, 0x40b0122202fe7f2e, 0xecf72c6fafacf2cb, 0x45dfc681f869f60a, 0x11814c9aff4af66c, 0x9278b0c4eea54fe7, 0x9a633d5baf7f2e2e, 0x69a329e6f1a05112, 0x1d874ace23e4}} - - // x(P) = 8172151271761071554796221948801462094972242987811852753144865524899433583596839357223411088919388342364651632180452081960511516040935428737829624206426287774255114241789158000915683252363913079335550843837650671094705509470594*i + 9326574858039944121604015439381720195556183422719505497448541073272720545047742235526963773359004021838961919129020087515274115525812121436661025030481584576474033630899768377131534320053412545346268645085054880212827284581557 - affine_xP = Fp2Element{ - A: FpElement{0xe8d05f30aac47247, 0x576ec00c55441de7, 0xbf1a8ec5fe558518, 0xd77cb17f77515881, 0x8e9852837ee73ec4, 0x8159634ad4f44a6b, 0x2e4eb5533a798c5, 0x9be8c4354d5bc849, 0xf47dc61806496b84, 0x25d0e130295120e0, 0xdbef54095f8139e3, 0x5a724f20862c}, - B: FpElement{0x3ca30d7623602e30, 0xfb281eddf45f07b7, 0xd2bf62d5901a45bc, 0xc67c9baf86306dd2, 0x4e2bd93093f538ca, 0xcfd92075c25b9cbe, 0xceafe9a3095bcbab, 0x7d928ad380c85414, 0x37c5f38b2afdc095, 0x75325899a7b779f4, 0xf130568249f20fdd, 0x178f264767d1}} - - // x([2]P) = 1476586462090705633631615225226507185986710728845281579274759750260315746890216330325246185232948298241128541272709769576682305216876843626191069809810990267291824247158062860010264352034514805065784938198193493333201179504845*i + 3623708673253635214546781153561465284135688791018117615357700171724097420944592557655719832228709144190233454198555848137097153934561706150196041331832421059972652530564323645509890008896574678228045006354394485640545367112224 - affine_xP2 = Fp2Element{ - A: FpElement{0x2a77afa8576ce979, 0xab1360e69b0aeba0, 0xd79e3e3cbffad660, 0x5fd0175aa10f106b, 0x1800ebafce9fbdbc, 0x228fc9142bdd6166, 0x867cf907314e34c3, 0xa58d18c94c13c31c, 0x699a5bc78b11499f, 0xa29fc29a01f7ccf1, 0x6c69c0c5347eebce, 0x38ecee0cc57}, - B: FpElement{0x43607fd5f4837da0, 0x560bad4ce27f8f4a, 0x2164927f8495b4dd, 0x621103fdb831a997, 0xad740c4eea7db2db, 0x2cde0442205096cd, 0x2af51a70ede8324e, 0x41a4e680b9f3466, 0x5481f74660b8f476, 0xfcb2f3e656ff4d18, 0x42e3ce0837171acc, 0x44238c30530c}} - - // x([3]P) = 9351941061182433396254169746041546943662317734130813745868897924918150043217746763025923323891372857734564353401396667570940585840576256269386471444236630417779544535291208627646172485976486155620044292287052393847140181703665*i + 9010417309438761934687053906541862978676948345305618417255296028956221117900864204687119686555681136336037659036201780543527957809743092793196559099050594959988453765829339642265399496041485088089691808244290286521100323250273 - affine_xP3 = Fp2Element{ - A: FpElement{0x2096e3f23feca947, 0xf36f635aa4ad8634, 0xdae3b1c6983c5e9a, 0xe08df6c262cb74b4, 0xd2ca4edc37452d3d, 0xfb5f3fe42f500c79, 0x73740aa3abc2b21f, 0xd535fd869f914cca, 0x4a558466823fb67f, 0x3e50a7a0e3bfc715, 0xf43c6da9183a132f, 0x61aca1e1b8b9}, - B: FpElement{0x1e54ec26ea5077bd, 0x61380572d8769f9a, 0xc615170684f59818, 0x6309c3b93e84ef6e, 0x33c74b1318c3fcd0, 0xfe8d7956835afb14, 0x2d5a7b55423c1ecc, 0x869db67edfafea68, 0x1292632394f0a628, 0x10bba48225bfd141, 0x6466c28b408daba, 0x63cacfdb7c43}} - - // x([2^2]P) = 441719501189485559222919502512761433931671682884872259563221427434901842337947564993718830905758163254463901652874331063768876314142359813382575876106725244985607032091781306919778265250690045578695338669105227100119314831452*i + 6961734028200975729170216310486458180126343885294922940439352055937945948015840788921225114530454649744697857047401608073256634790353321931728699534700109268264491160589480994022419317695690866764726967221310990488404411684053 - affine_xP4 = Fp2Element{ - A: FpElement{0x6f9dbe4c39175153, 0xf2fec757eb99e88, 0x43d7361a93733d91, 0x3abd10ed19c85a3d, 0xc4de9ab9c5ef7181, 0x53e375901684c900, 0x68ffc3e7d71c41ff, 0x47adab62c8d942fe, 0x226a33fd6fbb381d, 0x87ef4c8fdd83309a, 0xaca1cf44c5fa8799, 0x6cbae86c755f}, - B: FpElement{0x4c80c37fe68282a7, 0xbd8b9d7248bf553a, 0x1fb0e8e74d5e1762, 0xb63fa0e4e5f91482, 0xc675ab8a45a1439, 0xdfa6772deace7820, 0xf0d813d71d9a9255, 0x53a1a58c634534bd, 0x4ebfc6485fdfd888, 0x6991fe4358bcf169, 0xc0547bdaca85b6fd, 0xf461548d632}} - - // x([3^2]P) = 3957171963425208493644602380039721164492341594850197356580248639045894821895524981729970650520936632013218950972842867220898274664982599375786979902471523505057611521217523103474682939638645404445093536997296151472632038973463*i + 1357869545269286021642168835877253886774707209614159162748874474269328421720121175566245719916322684751967981171882659798149072149161259103020057556362998810229937432814792024248155991141511691087135859252304684633946087474060 - affine_xP9 = Fp2Element{ - A: FpElement{0x7c0daa0f04ded4e0, 0x52dc4f883d85e065, 0x91afbdc2c1714d0b, 0xb7b3db8e658cfeba, 0x43d4e72a692882f3, 0x535c56d83753da30, 0xc8a58724433cbf5d, 0x351153c0a5e74219, 0x2c81827d19f93dd5, 0x26ef8aca3370ea1a, 0x1cf939a6dd225dec, 0x3403cb28ad41}, - B: FpElement{0x93e7bc373a9ff7b, 0x57b8cc47635ebc0f, 0x92eab55689106cf3, 0x93643111d421f24c, 0x1c58b519506f6b7a, 0xebd409fb998faa13, 0x5c86ed799d09d80e, 0xd9a1d764d6363562, 0xf95e87f92fb0c4cc, 0x6b2bbaf5632a5609, 0x2d9b6a809dfaff7f, 0x29c0460348b}} - - // m = 96550223052359874398280314003345143371473380422728857598463622014420884224892 - mScalarBytes = [...]uint8{0x7c, 0x7b, 0x95, 0xfa, 0xb4, 0x75, 0x6c, 0x48, 0x8c, 0x17, 0x55, 0xb4, 0x49, 0xf5, 0x1e, 0xa3, 0xb, 0x31, 0xf0, 0xa4, 0xa6, 0x81, 0xad, 0x94, 0x51, 0x11, 0xe7, 0xf5, 0x5b, 0x7d, 0x75, 0xd5} - - // x([m]P) = 7893578558852400052689739833699289348717964559651707250677393044951777272628231794999463214496545377542328262828965953246725804301238040891993859185944339366910592967840967752138115122568615081881937109746463885908097382992642*i + 8293895847098220389503562888233557012043261770526854885191188476280014204211818299871679993460086974249554528517413590157845430186202704783785316202196966198176323445986064452630594623103149383929503089342736311904030571524837 - affine_xaP = Fp2Element{ - A: FpElement{0x2112f3c7d7f938bb, 0x704a677f0a4df08f, 0x825370e31fb4ef00, 0xddbf79b7469f902, 0x27640c899ea739fd, 0xfb7b8b19f244108e, 0x546a6679dd3baebc, 0xe9f0ecf398d5265f, 0x223d2b350e75e461, 0x84b322a0b6aff016, 0xfabe426f539f8b39, 0x4507a0604f50}, - B: FpElement{0xac77737e5618a5fe, 0xf91c0e08c436ca52, 0xd124037bc323533c, 0xc9a772bf52c58b63, 0x3b30c8f38ef6af4d, 0xb9eed160e134f36e, 0x24e3836393b25017, 0xc828be1b11baf1d9, 0x7b7dab585df50e93, 0x1ca3852c618bd8e0, 0x4efa73bcb359fa00, 0x50b6a923c2d4}} - - // Inputs for testing 3-point-ladder - threePointLadderInputs = []ProjectivePoint{ - // x(P) - ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0xe8d05f30aac47247, 0x576ec00c55441de7, 0xbf1a8ec5fe558518, 0xd77cb17f77515881, 0x8e9852837ee73ec4, 0x8159634ad4f44a6b, 0x2e4eb5533a798c5, 0x9be8c4354d5bc849, 0xf47dc61806496b84, 0x25d0e130295120e0, 0xdbef54095f8139e3, 0x5a724f20862c}, - B: FpElement{0x3ca30d7623602e30, 0xfb281eddf45f07b7, 0xd2bf62d5901a45bc, 0xc67c9baf86306dd2, 0x4e2bd93093f538ca, 0xcfd92075c25b9cbe, 0xceafe9a3095bcbab, 0x7d928ad380c85414, 0x37c5f38b2afdc095, 0x75325899a7b779f4, 0xf130568249f20fdd, 0x178f264767d1}}, - Z: P751OneFp2, - }, - // x(Q) - ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x2b71a2a93ad1e10e, 0xf0b9842a92cfb333, 0xae17373615a27f5c, 0x3039239f428330c4, 0xa0c4b735ed7dcf98, 0x6e359771ddf6af6a, 0xe986e4cac4584651, 0x8233a2b622d5518, 0xbfd67bf5f06b818b, 0xdffe38d0f5b966a6, 0xa86b36a3272ee00a, 0x193e2ea4f68f}, - B: FpElement{0x5a0f396459d9d998, 0x479f42250b1b7dda, 0x4016b57e2a15bf75, 0xc59f915203fa3749, 0xd5f90257399cf8da, 0x1fb2dadfd86dcef4, 0x600f20e6429021dc, 0x17e347d380c57581, 0xc1b0d5fa8fe3e440, 0xbcf035330ac20e8, 0x50c2eb5f6a4f03e6, 0x86b7c4571}}, - Z: P751OneFp2, - }, - // x(P-Q) - ProjectivePoint{ - X: Fp2Element{ - A: FpElement{0x4aafa9f378f7b5ff, 0x1172a683aa8eee0, 0xea518d8cbec2c1de, 0xe191bcbb63674557, 0x97bc19637b259011, 0xdbeae5c9f4a2e454, 0x78f64d1b72a42f95, 0xe71cb4ea7e181e54, 0xe4169d4c48543994, 0x6198c2286a98730f, 0xd21d675bbab1afa5, 0x2e7269fce391}, - B: FpElement{0x23355783ce1d0450, 0x683164cf4ce3d93f, 0xae6d1c4d25970fd8, 0x7807007fb80b48cf, 0xa005a62ec2bbb8a2, 0x6b5649bd016004cb, 0xbb1a13fa1330176b, 0xbf38e51087660461, 0xe577fddc5dd7b930, 0x5f38116f56947cd3, 0x3124f30b98c36fde, 0x4ca9b6e6db37}}, - Z: P751OneFp2, - }, - } - curve = ProjectiveCurveParameters{A: curve_A, C: curve_C} - cln16prime, _ = new(big.Int).SetString("10354717741769305252977768237866805321427389645549071170116189679054678940682478846502882896561066713624553211618840202385203911976522554393044160468771151816976706840078913334358399730952774926980235086850991501872665651576831", 10) -) - -/* ------------------------------------------------------------------------- - Values used by benchmarking tools - -------------------------------------------------------------------------*/ - -// Package-level storage for this field element is intended to deter -// compiler optimizations. -var ( - benchmarkFpElement FpElement - benchmarkFpElementX2 FpElementX2 - bench_x = FpElement{17026702066521327207, 5108203422050077993, 10225396685796065916, 11153620995215874678, 6531160855165088358, 15302925148404145445, 1248821577836769963, 9789766903037985294, 7493111552032041328, 10838999828319306046, 18103257655515297935, 27403304611634} - bench_y = FpElement{4227467157325093378, 10699492810770426363, 13500940151395637365, 12966403950118934952, 16517692605450415877, 13647111148905630666, 14223628886152717087, 7167843152346903316, 15855377759596736571, 4300673881383687338, 6635288001920617779, 30486099554235} - bench_z = FpElementX2{1595347748594595712, 10854920567160033970, 16877102267020034574, 12435724995376660096, 3757940912203224231, 8251999420280413600, 3648859773438820227, 17622716832674727914, 11029567000887241528, 11216190007549447055, 17606662790980286987, 4720707159513626555, 12887743598335030915, 14954645239176589309, 14178817688915225254, 1191346797768989683, 12629157932334713723, 6348851952904485603, 16444232588597434895, 7809979927681678066, 14642637672942531613, 3092657597757640067, 10160361564485285723, 240071237} -) - -// Helpers -func (primeElement primeFieldElement) String() string { - b := toBigInt(&primeElement.A) - return fmt.Sprintf("%X", b.String()) -} - -/* ------------------------------------------------------------------------- - Helpers - -------------------------------------------------------------------------*/ - -// Given xP = x(P), xQ = x(Q), and xPmQ = x(P-Q), compute xR = x(P+Q). -// -// Returns xR to allow chaining. Safe to overlap xP, xQ, xR. -func AddProjFp2(xP, xQ, xPmQ *ProjectivePoint) ProjectivePoint { - // Algorithm 1 of Costello-Smith. - var v0, v1, v2, v3, v4 Fp2Element - var xR ProjectivePoint - kFieldOps.Add(&v0, &xP.X, &xP.Z) // X_P + Z_P - kFieldOps.Sub(&v1, &xQ.X, &xQ.Z) - kFieldOps.Mul(&v1, &v1, &v0) // (X_Q - Z_Q)(X_P + Z_P) - kFieldOps.Sub(&v0, &xP.X, &xP.Z) // X_P - Z_P - kFieldOps.Add(&v2, &xQ.X, &xQ.Z) - kFieldOps.Mul(&v2, &v2, &v0) // (X_Q + Z_Q)(X_P - Z_P) - kFieldOps.Add(&v3, &v1, &v2) - kFieldOps.Square(&v3, &v3) // 4(X_Q X_P - Z_Q Z_P)^2 - kFieldOps.Sub(&v4, &v1, &v2) - kFieldOps.Square(&v4, &v4) // 4(X_Q Z_P - Z_Q X_P)^2 - kFieldOps.Mul(&v0, &xPmQ.Z, &v3) // 4X_{P-Q}(X_Q X_P - Z_Q Z_P)^2 - kFieldOps.Mul(&xR.Z, &xPmQ.X, &v4) // 4Z_{P-Q}(X_Q Z_P - Z_Q X_P)^2 - xR.X = v0 - return xR -} - -// Given xP = x(P) and cached curve parameters Aplus2C = A + 2*C, C4 = 4*C, -// compute xQ = x([2]P). -// -// Returns xQ to allow chaining. Safe to overlap xP, xQ. -func DoubleProjFp2(xP *ProjectivePoint, Aplus2C, C4 *Fp2Element) ProjectivePoint { - // Algorithm 2 of Costello-Smith, amended to work with projective curve coefficients. - var v1, v2, v3, xz4 Fp2Element - var xQ ProjectivePoint - kFieldOps.Add(&v1, &xP.X, &xP.Z) // (X+Z)^2 - kFieldOps.Square(&v1, &v1) - kFieldOps.Sub(&v2, &xP.X, &xP.Z) // (X-Z)^2 - kFieldOps.Square(&v2, &v2) - kFieldOps.Sub(&xz4, &v1, &v2) // 4XZ = (X+Z)^2 - (X-Z)^2 - kFieldOps.Mul(&v2, &v2, C4) // 4C(X-Z)^2 - kFieldOps.Mul(&xQ.X, &v1, &v2) // 4C(X+Z)^2(X-Z)^2 - kFieldOps.Mul(&v3, &xz4, Aplus2C) // 4XZ(A + 2C) - kFieldOps.Add(&v3, &v3, &v2) // 4XZ(A + 2C) + 4C(X-Z)^2 - kFieldOps.Mul(&xQ.Z, &v3, &xz4) // (4XZ(A + 2C) + 4C(X-Z)^2)4XZ - // Now (xQ.x : xQ.z) - // = (4C(X+Z)^2(X-Z)^2 : (4XZ(A + 2C) + 4C(X-Z)^2)4XZ ) - // = ((X+Z)^2(X-Z)^2 : (4XZ((A + 2C)/4C) + (X-Z)^2)4XZ ) - // = ((X+Z)^2(X-Z)^2 : (4XZ((a + 2)/4) + (X-Z)^2)4XZ ) - return xQ -} - -// Given x(P) and a scalar m in little-endian bytes, compute x([m]P) using the -// Montgomery ladder. This is described in Algorithm 8 of Costello-Smith. -// -// This function's execution time is dependent only on the byte-length of the -// input scalar. All scalars of the same input length execute in uniform time. -// The scalar can be padded with zero bytes to ensure a uniform length. -// -// Safe to overlap the source with the destination. -func ScalarMult(curve *ProjectiveCurveParameters, xP *ProjectivePoint, scalar []uint8) ProjectivePoint { - var x0, x1, tmp ProjectivePoint - var Aplus2C, C4 Fp2Element - - kFieldOps.Add(&Aplus2C, &curve.C, &curve.C) // = 2*C - kFieldOps.Add(&C4, &Aplus2C, &Aplus2C) // = 4*C - kFieldOps.Add(&Aplus2C, &Aplus2C, &curve.A) // = 2*C + A - - x0.X = P751OneFp2 - x1 = *xP - - // Iterate over the bits of the scalar, top to bottom - prevBit := uint8(0) - for i := len(scalar) - 1; i >= 0; i-- { - scalarByte := scalar[i] - for j := 7; j >= 0; j-- { - bit := (scalarByte >> uint(j)) & 0x1 - kCurveOps.Params.Op.CondSwap(&x0.X, &x0.Z, &x1.X, &x1.Z, (bit ^ prevBit)) - //sProjectivePointConditionalSwap(&x0, &x1, (bit ^ prevBit)) - tmp = DoubleProjFp2(&x0, &Aplus2C, &C4) - x1 = AddProjFp2(&x0, &x1, xP) - x0 = tmp - prevBit = bit - } - } - // now prevBit is the lowest bit of the scalar - kCurveOps.Params.Op.CondSwap(&x0.X, &x0.Z, &x1.X, &x1.Z, prevBit) - return x0 -} - -// Returns true if lhs = rhs. Takes variable time. -func VartimeEqFp2(lhs, rhs *Fp2Element) bool { - a := *lhs - b := *rhs - - fp751StrongReduce(&a.A) - fp751StrongReduce(&a.B) - fp751StrongReduce(&b.A) - fp751StrongReduce(&b.B) - - eq := true - for i := 0; i < len(a.A) && eq; i++ { - eq = eq && (a.A[i] == b.A[i]) - eq = eq && (a.B[i] == b.B[i]) - } - return eq -} - -// Returns true if lhs = rhs. Takes variable time. -func VartimeEqProjFp2(lhs, rhs *ProjectivePoint) bool { - var t0, t1 Fp2Element - kFieldOps.Mul(&t0, &lhs.X, &rhs.Z) - kFieldOps.Mul(&t1, &lhs.Z, &rhs.X) - return VartimeEqFp2(&t0, &t1) -} - -func (GeneratedTestParams) generateFp2p751(rand *rand.Rand) Fp2Element { - // Generation strategy: low limbs taken from [0,2^64); high limb - // taken from smaller range - // - // Size hint is ignored since all elements are fixed size. - // - // Field elements taken in range [0,2p). Emulate this by capping - // the high limb by the top digit of 2*p-1: - // - // sage: (2*p-1).digits(2^64)[-1] - // 246065832128056 - // - // This still allows generating values >= 2p, but hopefully that - // excess is OK (and if it's not, we'll find out, because it's for - // testing...) - // - highLimb := rand.Uint64() % 246065832128056 - fpElementGen := func() FpElement { - return FpElement{ - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - rand.Uint64(), - highLimb, - } - } - return Fp2Element{A: fpElementGen(), B: fpElementGen()} -} - -func (c GeneratedTestParams) Generate(rand *rand.Rand, size int) reflect.Value { - return reflect.ValueOf( - GeneratedTestParams{ - ProjectivePoint{ - X: c.generateFp2p751(rand), - Z: c.generateFp2p751(rand), - }, - ProjectiveCurveParameters{ - A: c.generateFp2p751(rand), - C: c.generateFp2p751(rand), - }, - c.generateFp2p751(rand), - }) -} - -func (x primeFieldElement) Generate(rand *rand.Rand, size int) reflect.Value { - return reflect.ValueOf(primeFieldElement{ - A: new(GeneratedTestParams).generateFp2p751(rand).A}) -} - -// Convert an FpElement to a big.Int for testing. Because this is only -// for testing, no big.Int to FpElement conversion is provided. -func radix64ToBigInt(x []uint64) *big.Int { - radix := new(big.Int) - // 2^64 - radix.UnmarshalText(([]byte)("18446744073709551616")) - - base := new(big.Int).SetUint64(1) - val := new(big.Int).SetUint64(0) - tmp := new(big.Int) - - for _, xi := range x { - tmp.SetUint64(xi) - tmp.Mul(tmp, base) - val.Add(val, tmp) - base.Mul(base, radix) - } - - return val -} - -// Converts number from Montgomery domain and returns big.Int -func toBigInt(x *FpElement) *big.Int { - var fp Fp2Element - var in = Fp2Element{A: *x} - kFieldOps.FromMontgomery(&in, &fp) - return radix64ToBigInt(fp.A[:]) -} diff --git a/dh/sidh/params.go b/dh/sidh/params.go deleted file mode 100644 index 6d1ee17..0000000 --- a/dh/sidh/params.go +++ /dev/null @@ -1,82 +0,0 @@ -package sidh - -import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" - p503 "github.com/henrydcase/nobs/dh/sidh/p503" - p751 "github.com/henrydcase/nobs/dh/sidh/p751" -) - -// Keeps mapping: SIDH prime field ID to domain parameters -var sidhParams = make(map[uint8]SidhParams) - -// Params returns domain parameters corresponding to finite field and identified by -// `id` provieded by the caller. Function panics in case `id` wasn't registered earlier. -func Params(id uint8) *SidhParams { - if val, ok := sidhParams[id]; ok { - return &val - } - panic("sidh: SIDH Params ID unregistered") -} - -func init() { - p503 := SidhParams{ - Id: FP_503, - PublicKeySize: p503.P503_PublicKeySize, - SharedSecretSize: p503.P503_SharedSecretSize, - A: DomainParams{ - Affine_P: p503.P503_affine_PA, - Affine_Q: p503.P503_affine_QA, - Affine_R: p503.P503_affine_RA, - SecretBitLen: p503.P503_SecretBitLenA, - SecretByteLen: uint((p503.P503_SecretBitLenA + 7) / 8), - IsogenyStrategy: p503.P503_AliceIsogenyStrategy[:], - }, - B: DomainParams{ - Affine_P: p503.P503_affine_PB, - Affine_Q: p503.P503_affine_QB, - Affine_R: p503.P503_affine_RB, - SecretBitLen: p503.P503_SecretBitLenB, - SecretByteLen: uint((p503.P503_SecretBitLenB + 7) / 8), - IsogenyStrategy: p503.P503_BobIsogenyStrategy[:], - }, - OneFp2: p503.P503OneFp2, - HalfFp2: p503.P503HalfFp2, - MsgLen: 24, - // SIKEp503 provides 128 bit of classical security ([SIKE], 5.1) - KemSize: 16, - Bytelen: p503.P503_Bytelen, - Op: p503.FieldOperations(), - } - - p751 := SidhParams{ - Id: FP_751, - PublicKeySize: p751.P751_PublicKeySize, - SharedSecretSize: p751.P751_SharedSecretSize, - A: DomainParams{ - Affine_P: p751.P751_affine_PA, - Affine_Q: p751.P751_affine_QA, - Affine_R: p751.P751_affine_RA, - IsogenyStrategy: p751.P751_AliceIsogenyStrategy[:], - SecretBitLen: p751.P751_SecretBitLenA, - SecretByteLen: uint((p751.P751_SecretBitLenA + 7) / 8), - }, - B: DomainParams{ - Affine_P: p751.P751_affine_PB, - Affine_Q: p751.P751_affine_QB, - Affine_R: p751.P751_affine_RB, - IsogenyStrategy: p751.P751_BobIsogenyStrategy[:], - SecretBitLen: p751.P751_SecretBitLenB, - SecretByteLen: uint((p751.P751_SecretBitLenB + 7) / 8), - }, - OneFp2: p751.P751OneFp2, - HalfFp2: p751.P751HalfFp2, - MsgLen: 32, - // SIKEp751 provides 192 bit of classical security ([SIKE], 5.1) - KemSize: 24, - Bytelen: p751.P751_Bytelen, - Op: p751.FieldOperations(), - } - - sidhParams[FP_503] = p503 - sidhParams[FP_751] = p751 -} diff --git a/dh/sidh/sidh.go b/dh/sidh/sidh.go index 70639d2..6a0b281 100644 --- a/dh/sidh/sidh.go +++ b/dh/sidh/sidh.go @@ -1,302 +1,289 @@ package sidh import ( - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" + "errors" + "io" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" + "github.com/henrydcase/nobs/dh/sidh/internal/p434" + "github.com/henrydcase/nobs/dh/sidh/internal/p503" + "github.com/henrydcase/nobs/dh/sidh/internal/p751" ) -// ----------------------------------------------------------------------------- -// Functions for traversing isogeny trees acoording to strategy. Key type 'A' is +// I keep it bool in order to be able to apply logical NOT. +type KeyVariant uint + +// Base type for public and private key. Used mainly to carry domain +// parameters. +type key struct { + // Domain parameters of the algorithm to be used with a key + params *common.SidhParams + // Flag indicates wether corresponds to 2-, 3-torsion group or SIKE + keyVariant KeyVariant +} + +// Defines operations on public key +type PublicKey struct { + key + // x-coordinates of P,Q,P-Q in this exact order + affine3Pt [3]common.Fp2 +} + +// Defines operations on private key +type PrivateKey struct { + key + // Secret key + Scalar []byte + // Used only by KEM + S []byte +} + +// Id's correspond to bitlength of the prime field characteristic +// Currently Fp751 is the only one supported by this implementation +const ( + Fp434 = common.Fp434 + Fp503 = common.Fp503 + Fp751 = common.Fp751 +) + +const ( + // First 2 bits identify SIDH variant third bit indicates + // wether key is a SIKE variant (set) or SIDH (not set) + + // 001 - SIDH: corresponds to 2-torsion group + KeyVariantSidhA KeyVariant = 1 << 0 + // 010 - SIDH: corresponds to 3-torsion group + KeyVariantSidhB = 1 << 1 + // 110 - SIKE + KeyVariantSike = 1<<2 | KeyVariantSidhB +) + +// Accessor to key variant. +func (key *key) Variant() KeyVariant { + return key.keyVariant +} + +// NewPublicKey initializes public key. +// Usage of this function guarantees that the object is correctly initialized. +func NewPublicKey(id uint8, v KeyVariant) *PublicKey { + return &PublicKey{key: key{params: common.Params(id), keyVariant: v}} +} + +// Import clears content of the public key currently stored in the structure +// and imports key stored in the byte string. Returns error in case byte string +// size is wrong. Doesn't perform any validation. +func (pub *PublicKey) Import(input []byte) error { + if len(input) != pub.Size() { + return errors.New("sidh: input to short") + } + ssSz := pub.params.SharedSecretSize + common.BytesToFp2(&pub.affine3Pt[0], input[0:ssSz], pub.params.Bytelen) + common.BytesToFp2(&pub.affine3Pt[1], input[ssSz:2*ssSz], pub.params.Bytelen) + common.BytesToFp2(&pub.affine3Pt[2], input[2*ssSz:3*ssSz], pub.params.Bytelen) + switch pub.params.ID { + case Fp434: + p434.ToMontgomery(&pub.affine3Pt[0], &pub.affine3Pt[0]) + p434.ToMontgomery(&pub.affine3Pt[1], &pub.affine3Pt[1]) + p434.ToMontgomery(&pub.affine3Pt[2], &pub.affine3Pt[2]) + case Fp503: + p503.ToMontgomery(&pub.affine3Pt[0], &pub.affine3Pt[0]) + p503.ToMontgomery(&pub.affine3Pt[1], &pub.affine3Pt[1]) + p503.ToMontgomery(&pub.affine3Pt[2], &pub.affine3Pt[2]) + case Fp751: + p751.ToMontgomery(&pub.affine3Pt[0], &pub.affine3Pt[0]) + p751.ToMontgomery(&pub.affine3Pt[1], &pub.affine3Pt[1]) + p751.ToMontgomery(&pub.affine3Pt[2], &pub.affine3Pt[2]) + default: + panic("Unsupported key") + } + return nil +} + +// Exports currently stored key. In case structure hasn't been filled with key data +// returned byte string is filled with zeros. +func (pub *PublicKey) Export(out []byte) { + var feTmp [3]common.Fp2 + ssSz := pub.params.SharedSecretSize + switch pub.params.ID { + case Fp434: + p434.FromMontgomery(&feTmp[0], &pub.affine3Pt[0]) + p434.FromMontgomery(&feTmp[1], &pub.affine3Pt[1]) + p434.FromMontgomery(&feTmp[2], &pub.affine3Pt[2]) + case Fp503: + p503.FromMontgomery(&feTmp[0], &pub.affine3Pt[0]) + p503.FromMontgomery(&feTmp[1], &pub.affine3Pt[1]) + p503.FromMontgomery(&feTmp[2], &pub.affine3Pt[2]) + case Fp751: + p751.FromMontgomery(&feTmp[0], &pub.affine3Pt[0]) + p751.FromMontgomery(&feTmp[1], &pub.affine3Pt[1]) + p751.FromMontgomery(&feTmp[2], &pub.affine3Pt[2]) + default: + panic("Unsupported key") + } + common.Fp2ToBytes(out[0:ssSz], &feTmp[0], pub.params.Bytelen) + common.Fp2ToBytes(out[ssSz:2*ssSz], &feTmp[1], pub.params.Bytelen) + common.Fp2ToBytes(out[2*ssSz:3*ssSz], &feTmp[2], pub.params.Bytelen) +} + +// Size returns size of the public key in bytes. +func (pub *PublicKey) Size() int { + return pub.params.PublicKeySize +} + +// NewPrivateKey initializes private key. +// Usage of this function guarantees that the object is correctly initialized. +func NewPrivateKey(id uint8, v KeyVariant) *PrivateKey { + prv := &PrivateKey{key: key{params: common.Params(id), keyVariant: v}} + if (v & KeyVariantSidhA) == KeyVariantSidhA { + prv.Scalar = make([]byte, prv.params.A.SecretByteLen) + } else { + prv.Scalar = make([]byte, prv.params.B.SecretByteLen) + } + if v == KeyVariantSike { + prv.S = make([]byte, prv.params.MsgLen) + } + return prv +} + +// Exports currently stored key. In case structure hasn't been filled with key data +// returned byte string is filled with zeros. +func (prv *PrivateKey) Export(out []byte) { + copy(out, prv.S) + copy(out[len(prv.S):], prv.Scalar) +} + +// Size returns size of the private key in bytes. +func (prv *PrivateKey) Size() int { + tmp := len(prv.Scalar) + if prv.Variant() == KeyVariantSike { + tmp += prv.params.MsgLen + } + return tmp +} + +// Size returns size of the shared secret. +func (prv *PrivateKey) SharedSecretSize() int { + return prv.params.SharedSecretSize +} + +// Import clears content of the private key currently stored in the structure +// and imports key from octet string. In case of SIKE, the random value 'S' +// must be prepended to the value of actual private key (see SIKE spec for details). +// Function doesn't import public key value to PrivateKey object. +func (prv *PrivateKey) Import(input []byte) error { + if len(input) != prv.Size() { + return errors.New("sidh: input to short") + } + copy(prv.S, input[:len(prv.S)]) + copy(prv.Scalar, input[len(prv.S):]) + return nil +} + +// Generates random private key for SIDH or SIKE. Generated value is +// formed as little-endian integer from key-space <2^(e2-1)..2^e2 - 1> +// for KeyVariant_A or <2^(s-1)..2^s - 1>, where s = floor(log_2(3^e3)), +// for KeyVariant_B. // +// Returns error in case user provided RNG fails. +func (prv *PrivateKey) Generate(rand io.Reader) error { + var dp *common.DomainParams -// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed -// for public key generation. -func traverseTreePublicKeyA(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint, pub *PublicKey) { - var points = make([]ProjectivePoint, 0, 8) - var indices = make([]int, 0, 8) - var i, sidx int - var op = CurveOperations{Params: pub.params} + if (prv.keyVariant & KeyVariantSidhA) == KeyVariantSidhA { + dp = &prv.params.A + } else { + dp = &prv.params.B + } - cparam := op.CalcCurveParamsEquiv4(curve) - phi := Newisogeny4(op.Params.Op) - strat := pub.params.A.IsogenyStrategy - stratSz := len(strat) - - for j := 1; j <= stratSz; j++ { - for i <= stratSz-j { - points = append(points, *xR) - indices = append(indices, i) - - k := strat[sidx] - sidx++ - op.Pow2k(xR, &cparam, 2*k) - i += int(k) + if prv.keyVariant == KeyVariantSike { + if _, err := io.ReadFull(rand, prv.S); err != nil { + return err } + } - cparam = phi.GenerateCurve(xR) - for k := 0; k < len(points); k++ { - points[k] = phi.EvaluatePoint(&points[k]) + // Private key generation takes advantage of the fact that keyspace for secret + // key is (0, 2^x - 1), for some possitivite value of 'x' (see SIKE, 1.3.8). + // It means that all bytes in the secret key, but the last one, can take any + // value between <0x00,0xFF>. Similarly for the last byte, but generation + // needs to chop off some bits, to make sure generated value is an element of + // a key-space. + if _, err := io.ReadFull(rand, prv.Scalar); err != nil { + return err + } + + prv.Scalar[len(prv.Scalar)-1] &= (1 << (dp.SecretBitLen % 8)) - 1 + // Make sure scalar is SecretBitLen long. SIKE spec says that key + // space starts from 0, but I'm not comfortable with having low + // value scalars used for private keys. It is still secrure as per + // table 5.1 in [SIKE]. + prv.Scalar[len(prv.Scalar)-1] |= 1 << ((dp.SecretBitLen % 8) - 1) + + return nil +} + +// Generates public key. +func (prv *PrivateKey) GeneratePublicKey(pub *PublicKey) { + var isA = (prv.keyVariant & KeyVariantSidhA) == KeyVariantSidhA + + if (pub.keyVariant != prv.keyVariant) || (pub.params.ID != prv.params.ID) { + panic("sidh: incompatbile public key") + } + + switch prv.params.ID { + case Fp434: + if isA { + p434.PublicKeyGenA(&pub.affine3Pt, prv.Scalar) + } else { + p434.PublicKeyGenB(&pub.affine3Pt, prv.Scalar) } - - *phiP = phi.EvaluatePoint(phiP) - *phiQ = phi.EvaluatePoint(phiQ) - *phiR = phi.EvaluatePoint(phiR) - - // pop xR from points - *xR, points = points[len(points)-1], points[:len(points)-1] - i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] + case Fp503: + if isA { + p503.PublicKeyGenA(&pub.affine3Pt, prv.Scalar) + } else { + p503.PublicKeyGenB(&pub.affine3Pt, prv.Scalar) + } + case Fp751: + if isA { + p751.PublicKeyGenA(&pub.affine3Pt, prv.Scalar) + } else { + p751.PublicKeyGenB(&pub.affine3Pt, prv.Scalar) + } + default: + panic("Field not supported") } } -// Traverses isogeny tree in order to compute xR needed -// for public key generation. -func traverseTreeSharedKeyA(curve *ProjectiveCurveParameters, xR *ProjectivePoint, pub *PublicKey) { - var points = make([]ProjectivePoint, 0, 8) - var indices = make([]int, 0, 8) - var i, sidx int - var op = CurveOperations{Params: pub.params} - - cparam := op.CalcCurveParamsEquiv4(curve) - phi := Newisogeny4(op.Params.Op) - strat := pub.params.A.IsogenyStrategy - stratSz := len(strat) - - for j := 1; j <= stratSz; j++ { - for i <= stratSz-j { - points = append(points, *xR) - indices = append(indices, i) - - k := strat[sidx] - sidx++ - op.Pow2k(xR, &cparam, 2*k) - i += int(k) - } - - cparam = phi.GenerateCurve(xR) - for k := 0; k < len(points); k++ { - points[k] = phi.EvaluatePoint(&points[k]) - } - - // pop xR from points - *xR, points = points[len(points)-1], points[:len(points)-1] - i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] - } -} - -// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed -// for public key generation. -func traverseTreePublicKeyB(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint, pub *PublicKey) { - var points = make([]ProjectivePoint, 0, 8) - var indices = make([]int, 0, 8) - var i, sidx int - var op = CurveOperations{Params: pub.params} - - cparam := op.CalcCurveParamsEquiv3(curve) - phi := Newisogeny3(op.Params.Op) - strat := pub.params.B.IsogenyStrategy - stratSz := len(strat) - - for j := 1; j <= stratSz; j++ { - for i <= stratSz-j { - points = append(points, *xR) - indices = append(indices, i) - - k := strat[sidx] - sidx++ - op.Pow3k(xR, &cparam, k) - i += int(k) - } - - cparam = phi.GenerateCurve(xR) - for k := 0; k < len(points); k++ { - points[k] = phi.EvaluatePoint(&points[k]) - } - - *phiP = phi.EvaluatePoint(phiP) - *phiQ = phi.EvaluatePoint(phiQ) - *phiR = phi.EvaluatePoint(phiR) - - // pop xR from points - *xR, points = points[len(points)-1], points[:len(points)-1] - i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] - } -} - -// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed -// for public key generation. -func traverseTreeSharedKeyB(curve *ProjectiveCurveParameters, xR *ProjectivePoint, pub *PublicKey) { - var points = make([]ProjectivePoint, 0, 8) - var indices = make([]int, 0, 8) - var i, sidx int - var op = CurveOperations{Params: pub.params} - - cparam := op.CalcCurveParamsEquiv3(curve) - phi := Newisogeny3(op.Params.Op) - strat := pub.params.B.IsogenyStrategy - stratSz := len(strat) - - for j := 1; j <= stratSz; j++ { - for i <= stratSz-j { - points = append(points, *xR) - indices = append(indices, i) - - k := strat[sidx] - sidx++ - op.Pow3k(xR, &cparam, k) - i += int(k) - } - - cparam = phi.GenerateCurve(xR) - for k := 0; k < len(points); k++ { - points[k] = phi.EvaluatePoint(&points[k]) - } - - // pop xR from points - *xR, points = points[len(points)-1], points[:len(points)-1] - i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1] - } -} - -// Generate a public key in the 2-torsion group -func publicKeyGenA(prv *PrivateKey) (pub *PublicKey) { - var xPA, xQA, xRA ProjectivePoint - var xPB, xQB, xRB, xR ProjectivePoint - var invZP, invZQ, invZR Fp2Element - var tmp ProjectiveCurveParameters - - pub = NewPublicKey(prv.params.Id, KeyVariant_SIDH_A) - var op = CurveOperations{Params: pub.params} - var phi = Newisogeny4(op.Params.Op) - - // Load points for A - xPA = ProjectivePoint{X: prv.params.A.Affine_P, Z: prv.params.OneFp2} - xQA = ProjectivePoint{X: prv.params.A.Affine_Q, Z: prv.params.OneFp2} - xRA = ProjectivePoint{X: prv.params.A.Affine_R, Z: prv.params.OneFp2} - - // Load points for B - xRB = ProjectivePoint{X: prv.params.B.Affine_R, Z: prv.params.OneFp2} - xQB = ProjectivePoint{X: prv.params.B.Affine_Q, Z: prv.params.OneFp2} - xPB = ProjectivePoint{X: prv.params.B.Affine_P, Z: prv.params.OneFp2} - - // Find isogeny kernel - tmp.C = pub.params.OneFp2 - xR = op.ScalarMul3Pt(&tmp, &xPA, &xQA, &xRA, prv.params.A.SecretBitLen, prv.Scalar) - - // Reset params object and travers isogeny tree - tmp.C = pub.params.OneFp2 - tmp.A.Zeroize() - traverseTreePublicKeyA(&tmp, &xR, &xPB, &xQB, &xRB, pub) - - // Secret isogeny - phi.GenerateCurve(&xR) - xPA = phi.EvaluatePoint(&xPB) - xQA = phi.EvaluatePoint(&xQB) - xRA = phi.EvaluatePoint(&xRB) - op.Fp2Batch3Inv(&xPA.Z, &xQA.Z, &xRA.Z, &invZP, &invZQ, &invZR) - - op.Params.Op.Mul(&pub.affine_xP, &xPA.X, &invZP) - op.Params.Op.Mul(&pub.affine_xQ, &xQA.X, &invZQ) - op.Params.Op.Mul(&pub.affine_xQmP, &xRA.X, &invZR) - return -} - -// Generate a public key in the 3-torsion group -func publicKeyGenB(prv *PrivateKey) (pub *PublicKey) { - var xPB, xQB, xRB, xR ProjectivePoint - var xPA, xQA, xRA ProjectivePoint - var invZP, invZQ, invZR Fp2Element - var tmp ProjectiveCurveParameters - - pub = NewPublicKey(prv.params.Id, prv.keyVariant) - var op = CurveOperations{Params: pub.params} - var phi = Newisogeny3(op.Params.Op) - - // Load points for B - xRB = ProjectivePoint{X: prv.params.B.Affine_R, Z: prv.params.OneFp2} - xQB = ProjectivePoint{X: prv.params.B.Affine_Q, Z: prv.params.OneFp2} - xPB = ProjectivePoint{X: prv.params.B.Affine_P, Z: prv.params.OneFp2} - - // Load points for A - xPA = ProjectivePoint{X: prv.params.A.Affine_P, Z: prv.params.OneFp2} - xQA = ProjectivePoint{X: prv.params.A.Affine_Q, Z: prv.params.OneFp2} - xRA = ProjectivePoint{X: prv.params.A.Affine_R, Z: prv.params.OneFp2} - - tmp.C = pub.params.OneFp2 - xR = op.ScalarMul3Pt(&tmp, &xPB, &xQB, &xRB, prv.params.B.SecretBitLen, prv.Scalar) - - tmp.C = pub.params.OneFp2 - tmp.A.Zeroize() - traverseTreePublicKeyB(&tmp, &xR, &xPA, &xQA, &xRA, pub) - - phi.GenerateCurve(&xR) - xPB = phi.EvaluatePoint(&xPA) - xQB = phi.EvaluatePoint(&xQA) - xRB = phi.EvaluatePoint(&xRA) - op.Fp2Batch3Inv(&xPB.Z, &xQB.Z, &xRB.Z, &invZP, &invZQ, &invZR) - - op.Params.Op.Mul(&pub.affine_xP, &xPB.X, &invZP) - op.Params.Op.Mul(&pub.affine_xQ, &xQB.X, &invZQ) - op.Params.Op.Mul(&pub.affine_xQmP, &xRB.X, &invZR) - return -} - -// ----------------------------------------------------------------------------- -// Key agreement functions +// Computes a SIDH shared secret. Function requires that pub has different +// KeyVariant than prv. Length of returned output is 2*ceil(log_2 P)/8), +// where P is a prime defining finite field. // +// Caller must make sure key SIDH key pair is not used more than once. +func (prv *PrivateKey) DeriveSecret(ss []byte, pub *PublicKey) { + var isA = (prv.keyVariant & KeyVariantSidhA) == KeyVariantSidhA -// Establishing shared keys in in 2-torsion group -func deriveSecretA(prv *PrivateKey, pub *PublicKey) []byte { - var sharedSecret = make([]byte, pub.params.SharedSecretSize) - var cparam ProjectiveCurveParameters - var xP, xQ, xQmP ProjectivePoint - var xR ProjectivePoint - var op = CurveOperations{Params: prv.params} - var phi = Newisogeny4(op.Params.Op) + if (pub.keyVariant == prv.keyVariant) || (pub.params.ID != prv.params.ID) { + panic("sidh: public and private are incompatbile") + } - // Recover curve coefficients - cparam.C = pub.params.OneFp2 - op.RecoverCoordinateA(&cparam, &pub.affine_xP, &pub.affine_xQ, &pub.affine_xQmP) - - // Find kernel of the morphism - xP = ProjectivePoint{X: pub.affine_xP, Z: pub.params.OneFp2} - xQ = ProjectivePoint{X: pub.affine_xQ, Z: pub.params.OneFp2} - xQmP = ProjectivePoint{X: pub.affine_xQmP, Z: pub.params.OneFp2} - xR = op.ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, pub.params.A.SecretBitLen, prv.Scalar) - - // Traverse isogeny tree - traverseTreeSharedKeyA(&cparam, &xR, pub) - - // Calculate j-invariant on isogeneus curve - c := phi.GenerateCurve(&xR) - op.RecoverCurveCoefficients4(&cparam, &c) - op.Jinvariant(&cparam, sharedSecret) - return sharedSecret -} - -// Establishing shared keys in in 3-torsion group -func deriveSecretB(prv *PrivateKey, pub *PublicKey) []byte { - var sharedSecret = make([]byte, pub.params.SharedSecretSize) - var xP, xQ, xQmP ProjectivePoint - var xR ProjectivePoint - var cparam ProjectiveCurveParameters - var op = CurveOperations{Params: prv.params} - var phi = Newisogeny3(op.Params.Op) - - // Recover curve coefficients - cparam.C = pub.params.OneFp2 - op.RecoverCoordinateA(&cparam, &pub.affine_xP, &pub.affine_xQ, &pub.affine_xQmP) - - // Find kernel of the morphism - xP = ProjectivePoint{X: pub.affine_xP, Z: pub.params.OneFp2} - xQ = ProjectivePoint{X: pub.affine_xQ, Z: pub.params.OneFp2} - xQmP = ProjectivePoint{X: pub.affine_xQmP, Z: pub.params.OneFp2} - xR = op.ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, pub.params.B.SecretBitLen, prv.Scalar) - - // Traverse isogeny tree - traverseTreeSharedKeyB(&cparam, &xR, pub) - - // Calculate j-invariant on isogeneus curve - c := phi.GenerateCurve(&xR) - op.RecoverCurveCoefficients3(&cparam, &c) - op.Jinvariant(&cparam, sharedSecret) - return sharedSecret + switch prv.params.ID { + case Fp434: + if isA { + p434.DeriveSecretA(ss, prv.Scalar, &pub.affine3Pt) + } else { + p434.DeriveSecretB(ss, prv.Scalar, &pub.affine3Pt) + } + case Fp503: + if isA { + p503.DeriveSecretA(ss, prv.Scalar, &pub.affine3Pt) + } else { + p503.DeriveSecretB(ss, prv.Scalar, &pub.affine3Pt) + } + case Fp751: + if isA { + p751.DeriveSecretA(ss, prv.Scalar, &pub.affine3Pt) + } else { + p751.DeriveSecretB(ss, prv.Scalar, &pub.affine3Pt) + } + default: + panic("Field not supported") + } } diff --git a/dh/sidh/sidh_test.go b/dh/sidh/sidh_test.go index bd9ba4c..8160d0f 100644 --- a/dh/sidh/sidh_test.go +++ b/dh/sidh/sidh_test.go @@ -8,109 +8,133 @@ import ( "math/big" "testing" - . "github.com/henrydcase/nobs/dh/sidh/internal/isogeny" + "github.com/henrydcase/nobs/dh/sidh/internal/common" + . "github.com/henrydcase/nobs/internal/test" ) /* ------------------------------------------------------------------------- Test data -------------------------------------------------------------------------*/ -var tdata = map[uint8]struct { - name string - KatFile string - PkA string - PrA string - PkB string - PrB string -}{ - FP_503: { - name: "P-503", - PrA: "B0AD510708F4ABCF3E0D97DC2F2FF112D9D2AAE49D97FFD1E4267F21C6E71C03", - PrB: "A885A8B889520A6DBAD9FB33365E5B77FDED629440A16A533F259A510F63A822", - PkA: "A6BADBA04518A924B20046B59AC197DCDF0EA48014C9E228C4994CCA432F360E" + - "2D527AFB06CA7C96EE5CEE19BAD53BF9218A3961CAD7EC092BD8D9EBB22A3D51" + - "33008895A3F1F6A023F91E0FE06A00A622FD6335DAC107F8EC4283DC2632F080" + - "4E64B390DAD8A2572F1947C67FDF4F8787D140CE2C6B24E752DA9A195040EDFA" + - "C27333FAE97DBDEB41DA9EEB2DB067AE7DA8C58C0EF57AEFC18A3D6BD0576FF2" + - "F1CFCAEC50C958331BF631F3D2E769790C7B6DF282B74BBC02998AD10F291D47" + - "C5A762FF84253D3B3278BDF20C8D4D4AA317BE401B884E26A1F02C7308AADB68" + - "20EBDB0D339F5A63346F3B40CACED72F544DAF51566C6E807D0E6E1E38514342" + - "432661DC9564DA07548570E256688CD9E8060D8775F95D501886D958588CACA0" + - "9F2D2AE1913F996E76AF63E31A179A7A7D2A46EDA03B2BCCF9020A5AA15F9A28" + - "9340B33F3AE7F97360D45F8AE1B9DD48779A57E8C45B50A02C00349CD1C58C55" + - "1D68BC2A75EAFED944E8C599C288037181E997471352E24C952B", - PkB: "244AF1F367C2C33912750A98497CC8214BC195BD52BD76513D32ACE4B75E31F0" + - "281755C265F5565C74E3C04182B9C244071859C8588CC7F09547CEFF8F7705D2" + - "60CE87D6BFF914EE7DBE4B9AF051CA420062EEBDF043AF58184495026949B068" + - "98A47046BFAE8DF3B447746184AF550553BB5D266D6E1967ACA33CAC5F399F90" + - "360D70867F2C71EF6F94FF915C7DA8BC9549FB7656E691DAEFC93CF56876E482" + - "CA2F8BE2D6CDCC374C31AD8833CABE997CC92305F38497BEC4DFD1821B004FEC" + - "E16448F9A24F965EFE409A8939EEA671633D9FFCF961283E59B8834BDF7EDDB3" + - "05D6275B61DA6692325432A0BAA074FC7C1F51E76208AB193A57520D40A76334" + - "EE5712BDC3E1EFB6103966F2329EDFF63082C4DFCDF6BE1C5A048630B81871B8" + - "83B735748A8FD4E2D9530C272163AB18105B10015CA7456202FE1C9B92CEB167" + - "5EAE1132E582C88E47ED87B363D45F05BEA714D5E9933D7AF4071CBB5D49008F" + - "3E3DAD7DFF935EE509D5DE561842B678CCEB133D62E270E9AC3E", +type sidhVec struct { + id uint8 + name string + PkA string + PrA string + PkB string + PrB string +} + +var tdataSidh = map[uint8]sidhVec{ + Fp434: { + id: Fp434, + name: "P-434", + PrA: "3A727E04EA9B7E2A766A6F846489E7E7B915263BCEED308BB10FC900", + PrB: "E37BFE55B43B32448F375903D8D226EC94ADBFEA1D2B3536EB987001", + PkA: "9E668D1E6750ED4B91EE052C32839CA9DD2E56D52BC24DECC950AAAD" + + "24CEED3F9049C77FE80F0B9B01E7F8DAD7833EEC2286544D6380009C" + + "379CDD3E7517CEF5E20EB01F8231D52FC30DC61D2F63FB357F85DC63" + + "96E8A95DB9740BD3A972C8DB7901B31F074CD3E45345CA78F9008171" + + "30E688A29A7CF0073B5C00FF2C65FBE776918EF9BD8E75B29EF7FAB7" + + "91969B60B0C5B37A8992EDEF95FA7BAC40A95DAFE02E237301FEE9A7" + + "A43FD0B73477E8035DD12B73FAFEF18D39904DDE3653A754F36BE188" + + "8F6607C6A7951349A414352CF31A29F2C40302DB406C48018C905EB9" + + "DC46AFBF42A9187A9BB9E51B587622A2862DC7D5CC598BF38ED6320F" + + "B51D8697AD3D7A72ABCC32A393F0133DA8DF5E253D9E00B760B2DF34" + + "2FCE974DCFE946CFE4727783531882800F9E5DD594D6D5A6275EEFEF" + + "9713ED838F4A06BB34D7B8D46E0B385AAEA1C7963601", + PkB: "C9F73E4497AAA3FDF9EB688135866A8A83934BA10E273B8CC3808CF0" + + "C1F5FAB3E9BB295885881B73DEBC875670C0F51C4BB40DF5FEDE01B8" + + "AF32D1BF10508B8C17B2734EB93B2B7F5D84A4A0F2F816E9E2C32AC2" + + "53C0B6025B124D05A87A9E2A8567930F44BAA14219B941B6B400B4AE" + + "D1D796DA12A5A9F0B8F3F5EE9DD43F64CB24A3B1719DF278ADF56B5F" + + "3395187829DA2319DEABF6BBD6EDA244DE2B62CC5AC250C1009DD1CD" + + "4712B0B37406612AD002B5E51A62B51AC9C0374D143ABBBD58275FAF" + + "C4A5E959C54838C2D6D9FB43B7B2609061267B6A2E6C6D01D295C422" + + "3E0D3D7A4CDCFB28A7818A737935279751A6DD8290FD498D1F6AD5F4" + + "FFF6BDFA536713F509DCE8047252F1E7D0DD9FCC414C0070B5DCCE36" + + "65A21A032D7FBE749181032183AFAD240B7E671E87FBBEC3A8CA4C11" + + "AA7A9A23AC69AE2ACF54B664DECD27753D63508F1B02", }, - FP_751: { + Fp503: { + id: Fp503, + name: "P-503", + PrA: "D5B94224FA1AD1701EC277FDA83462D09E87181C2E583C5F09FD446A43F25103", + PrB: "FF0EF91753D71D83D912656856086007AD2CF3B2A979B2BD63E5313BFD276506", + PkA: "FFB9A589DBB3975A20373F1AD3B449880E1DA47916FCD7C751A019AAA8E95A03" + + "4ADA1AE8BFCF6FBF70F323713318E25315DE865B29C9124982594BF78CD61C09" + + "B98C22307DFD4FC0958C58EC0D144828006E510FA4072D721B48D1A3CFEA02F6" + + "062324FE1B68F457CF29BD4EB1FB68D0684EE69F53A3FAC327404341BB39365B" + + "5DE885034C9A6DD6798CB08126183C696D0302730D489584AC8D6BCADF3AB4DE" + + "FFC227D3B1701462DA15BF68EF2B07C44712DB5429B74063202F43DC0EA7919D" + + "B95025B2B03E5A3EBF57FF37E21838CE8F5531F491315E576A260DC2F515DDF2" + + "4DEDE54CA69737CE6442B4219CD472D9CCCF8AF12B5C5B23ACB9C22929924ABA" + + "52C820932C82435518B920AFC43F2041263AE98D29E58B73F33A5DD42AAC7533" + + "404B4AC2B83DD2C7BEA7676930B6007CC185C264672B75F5332C18429BBC7B0F" + + "2EA3F746995A298E7443FFB0C1B27DCA7D19635064AF3B87938960587F56B724" + + "C1EF1FF012B056D7301F8713295B7734563542D4259B8BEA260C", + PkB: "AA3303F79FCE4855DE125B239D10BEC3B7082E55B08C769A9765F1BF41A31210" + + "66382D6BF2857D85138CC17D69593B8FC7703D22C553FB077DFB3AC577CF1E55" + + "2AED6DC0368123E01DDD70059A47E31E06423D2F697A3DA5D621EB5FF2A52EE7" + + "CA7D3BD01B427AC14CB6099E03C6639A3BAC9B939297CEB10F276F93CF16A1EE" + + "1B8085DE3DA037C911491B145B034A47B42A996A61C2313FEF166FD3665B0AE8" + + "C201A268DA01AB52E4759ACCC1DD09685A17CDA5D44AF847931ABB221D62E241" + + "2329394445ADFD662C77472A9268F40AB540177C0E6F1D59026E595C46FBED2F" + + "703838C5F3D7A811B500237596C5E960AA1F2989C5F17DD60D8A752569DBF250" + + "E01C63C9790D014CE05A9D8683814A320E30185E478AF9ABD761DADDA8DE7E3E" + + "A53C224AC8313C176D14BD0F04AB09A9D0D0302ACBF768EB4DB03681EAE3BC10" + + "21CAA429A1490AE1D6E0CA9D6BC4BCD14B1CFE694226D03E8731E9E0B3760877" + + "7D56630B31298CC05B6FF6C1A08935312D8E95B8056AD7831A22", + }, + Fp751: { + id: Fp751, name: "P-751", // PrA - Alice's Private Key: 2*randint(0,2^371) - PrA: "C09957CC83045FB4C3726384D784476ACB6FFD92E5B15B3C2D451BA063F1BD4CED8FBCF682A98DD0954D3" + - "7BCAF730E", + PrA: "B1937F2B009FD9F785C5AD899F5ED2FD064218C07A76798D1433336E093DF184CA0CAF6E7C92B320E89632A7765F0B", // PrB - Bob's Private Key: 3*randint(0,3^238) - PrB: "393E8510E78A16D2DC1AACA9C9D17E7E78DB630881D8599C7040D05BB5557ECAE8165C45D5366ECB37B00" + - "969740AF201", - PkA: "74D8EF08CB74EC99BF08B6FBE4FB3D048873B67F018E44988B9D70C564D058401D20E093C7DF0C66F022C" + - "823E5139D2EA0EE137804B4820E950B046A90B0597759A0B6A197C56270128EA089FA1A2007DDE3430B37" + - "A3E6350BD47B7F513863741C125FA63DEDAFC475C13DB59E533055B7CBE4B2F32672DF2DF97E03E29617B" + - "0E9B6A35B58ABB26527A721142701EB147C7050E1D9125DA577B08CD51C8BB50627B8B47FACFC9C7C07DD" + - "00DD75115DD83719FD5F96115DED23ECAA50B1044C6BF3F27442DA284BA4A272D850F414FB185801BF2EF" + - "7E628EDB5643E35694B992CF30A2C5120CAF9434F09ACFCA3645B3FFC3A308901FAC7B8955FD5C98576AE" + - "FD03F5806CB7430F75B3431B75BEC080596ABCA26E637E6E8D4C25175A8C052C9CBE77900A863F83FAB00" + - "95B32D9C3858EF8A35B9F163D429E71DBA47539EB4791D117FE39DDE94EA7801A42DB12D84DE4740ACF51" + - "CD7C32BB854569D7D94E11E69D9663CC7ED02E78CF48F4069DF3D3E86198B307095C6B11D46C0DC849F9D" + - "94C7693209E5B3848AFAA6DA6A8D73362D779CBC43515902ED2BCE3A748C537DE2FCF092FD3E91B790AF5" + - "4E1092C5E5B89BE5BE23B955A52F769D97277EF69F820109042F28C316AC90AE69EB374C9280300B816E6" + - "2494B2E01072D1CA96E4B284D2BE1368D6969744B614FACBC8C165864E26E33481D4FDC47B6E523954A25" + - "C1A096A37CD23FB81AE64FB11BD0A439609F1CE40673B06DD96F698A910E935219D840F3D411EDFB00D98" + - "065AB9868C32D3DA05FF415", - PkB: "F6C260C4141E418457CB442E11F0F5558375437576E55D211D19EF83E2839E51D07A82765D8E7B6366FA7" + - "0B56CDE3AD3B629ACF542A433369496EDA51EDFBE16EFA1B8DEE1CE46B37820ECBD0CD674AACD4F21FABC" + - "2436651E3AF604356FF3EB2CA87976890E34A56FAEC9A2ACD9559B1BB67B69AC1A521342E1E787DA5D709" + - "32B0F5842ECA1C99B269DB6C2ED8397F0FC49F114CF8B5AF327A698C0251575CDD1D67732668109A91A3B" + - "FA5B47D413C7FAB8817FCBEBFE9BDD9C0B1F3B1934A7028A65233E8B58A92E7E9F66B68B2057ECBF7E44A" + - "0EF6EFCC3C8AA5414E100FA0C24F7545324AD17062FC11377A2A4749DEE27E192460E099DBDA8E840EA11" + - "AD9D5C83DF065AF77030E7FE18CE24CFC71D356B9B9601811B93676C12CB6B41747133D5259E7A20CC065" + - "FAB99DF944FDB34ABB9A374F9E9CC8F9C186BD2181DC2771F69C02629C3E4801A7E7C21F6F3CFF7D257E2" + - "257C88C015F0CC8DC0E7FB3373CF4ED6A786AB329E7F16895CA147AD91F6EAE1DFE38116580DF52381599" + - "E4246278CB1848FE4A56ABF98652E9E7C2E681551A3D78FA033D932087D8B6567D779A56B726B153033D7" + - "2231A1B5C16ED7DC4458308D6B64AF6723CC0F52C94E04C58FCA9739E890AA40CC05E22321F10129D2B59" + - "1F317102034C109A56D711591E5B44C717CFC9C9B9461894767CAFA42D2B394194B03999C2A9EF48868F3" + - "FB03D1A40F596613AF97F4ED7643A1C2D12692E959C6DEB8E72403ADC0E42204DBCE5056EEF0CC60B0C6E" + - "83B8B55AC01F6C85644EE49", + PrB: "54DB4380D4134E187F5793FA82A4F18B39CA2F8F1C145FFB040FC917E2F41542037FF227F3A4AAFB17A6983AA88B4403", + PkA: "2B53BB7C002A9D18B077D068C38353ADFD57A3CA0E431D92CCB8060D41A83A09" + + "C1500BEE63FB07DA1DBEDB4AF145F22C2D8152B07B7E124F06643C7AB5B1C48D" + + "581FC4C6FB7FC165F6E02F40B47D81400B84B6288DEAB38DE795B51486430974" + + "788377770D46B0ABC1F3F7C3647A0E38ACED475EA8EE990F3C5A7668452478C1" + + "975993E126B405E476AD6A10E9DD4E135ADA910BE41A8F93331268791F7B958A" + + "0888052D1CF7B9128058A258002F22AC48E2C296E3935033139D336FDEB33E9B" + + "8713663B1705B566AC4F4455FD0E710A5236C18011EA971DDD18633F9022C432" + + "B225EC401FCD4C233B8BF91BE5944D1A657516CE4B844D0BC6049478046B60B6" + + "BE163E41CCE743054806B13FAC0A1FA393C866D74A5A93A938209287324FAB46" + + "295F5B271C9D8CFEE17868599202D7AEF1A67EBE2FA2A27AD9E0991CEDEE270D" + + "1E7639425D94A0F0A2EFDE90B86D5D7F03F3CF97D30415CAA661F865ADB788E6" + + "3F79EE2FE8637D9DCAF3BCD5C42AE499688048BBB49F216B4714675FD87F7CCC" + + "37A0C2EA56BB53675584F7648BA052F963C35387ECC4DDED4F8076934FF32D5D" + + "77B5D3C57553757A4CB9588C4575D4CC4CA8280370041A6FF03007C31D0712E8" + + "327CC5BC9885F896904FAB4EE167745260D331C3E85E8A32FCCD23093F2C55A9" + + "EA8D7BECEFC3564D3C3D4CE585B62785773B2228742185C97D6F51CD3E3CF885" + + "5CF37F305734E97A86479580FDB9983DDCAE9D0F1B125523DB2FE58339240A58" + + "131D0EFD14A560A6F7EDE774F6C3C54F46DD0830", + PkB: "E93E4E2B0E7348C088FD91F8E3B17CC52B55C5E8933B6D00B3757E5347C5A0AE" + + "5F1A6051C32FB20A41013A244484C8D0501B6A3516A634581E08C907F29D651C" + + "BCC5B6CA6BAC4DCC980CD36155B60A2108134D3F78ED19ADA2B8B20184302FD7" + + "47E096B01ABB33CB76B115D673B00F76913281CF7A0B44FF5CF1A256B8138FE6" + + "77AB8D22FEBBCB10EB46E442D0AD96A126DD24E941280C7AB3F9FAC2832A149C" + + "AD93D221EDCB406303F5A1B38F43F310244D766239A7F4D89EED4C6FD272BC4F" + + "F7C4E34F3E5E77BFF59D6FE5C0D3937F574ABE81C2FC1FEDD98F43323F8F2D7C" + + "154DCEBF410FCF698A4E6506D6FD6E4A861395F75698C810A527E00ADC118C90" + + "9CDE7729B24C6E7DE9C92CFB592CB9A4BAC54DB468AA52724452CC7A7B40509B" + + "B7894ACCF2C7933537FD52DB312D7FBC4FDE01AC2350CD25ABDD5E6F3AEF87BA" + + "1BE23691544EB6A4F8FA9CF2BE70B9665EA479B44DC3C61D4651CDDB53656B6F" + + "3A2D139EC6BE8550B8A623CCA30EB5374F70C67A932712002006F3D73190384F" + + "6D3BEC9DB9F46E9B7AE2891E615752E74DC112579CF43283E8B6EBEF4C802BD6" + + "700A97B9739E8694B48D8CB9C8ABBC915A834FF1DBF2C823B3E156D0A415C558" + + "71B719BD9DD215F57C8D19A6B4F8CD93283D6EBD135347DAAF4F20C54D24017F" + + "5E6AF400AB6DC98AD2D5810E59360DF64503599FAF6FBAB720CC557DEEF0F528" + + "249DEB530C8F310465E0BE2B4041C24DAF783BC4EE71D27C760FA7CFD4A9A691" + + "70BCBA465CA242961671DF0C53A8112CCD708D58", }, } /* ------------------------------------------------------------------------- Helpers -------------------------------------------------------------------------*/ -// Fail if err !=nil. Display msg as an error message -func checkErr(t testing.TB, err error, msg string) { - if err != nil { - t.Error(msg) - } -} - -// Utility used for running same test with all registered prime fields -type MultiIdTestingFunc func(testing.TB, uint8) - -func Do(f MultiIdTestingFunc, t testing.TB) { - for id, val := range tdata { - fmt.Printf("\tTesting: %s\n", val.name) - f(t, id) - } -} - -// Converts string to private key +// Converts string to private key. func convToPrv(s string, v KeyVariant, id uint8) *PrivateKey { key := NewPrivateKey(id, v) hex, e := hex.DecodeString(s) @@ -124,7 +148,7 @@ func convToPrv(s string, v KeyVariant, id uint8) *PrivateKey { return key } -// Converts string to public key +// Converts string to public key. func convToPub(s string, v KeyVariant, id uint8) *PublicKey { key := NewPublicKey(id, v) hex, e := hex.DecodeString(s) @@ -138,135 +162,148 @@ func convToPub(s string, v KeyVariant, id uint8) *PublicKey { return key } -/* ------------------------------------------------------------------------- - Unit tests - -------------------------------------------------------------------------*/ -func testKeygen(t testing.TB, id uint8) { - prvB := NewPrivateKey(id, KeyVariant_SIDH_B) - err := prvB.Generate(rand.Reader) - checkErr(t, err, "key generation failed") +/* Unit tests */ - alicePrivate := convToPrv(tdata[id].PrA, KeyVariant_SIDH_A, id) - bobPrivate := convToPrv(tdata[id].PrB, KeyVariant_SIDH_B, id) - expPubA := convToPub(tdata[id].PkA, KeyVariant_SIDH_A, id) - expPubB := convToPub(tdata[id].PkB, KeyVariant_SIDH_B, id) +func testKeygen(t *testing.T, v sidhVec) { + pubA := NewPublicKey(v.id, KeyVariantSidhA) + pubB := NewPublicKey(v.id, KeyVariantSidhB) + alicePrivate := convToPrv(v.PrA, KeyVariantSidhA, v.id) + bobPrivate := convToPrv(v.PrB, KeyVariantSidhB, v.id) + expPubA := convToPub(v.PkA, KeyVariantSidhA, v.id) + expPubB := convToPub(v.PkB, KeyVariantSidhB, v.id) - pubA := alicePrivate.GeneratePublicKey() - pubB := bobPrivate.GeneratePublicKey() + alicePrivate.GeneratePublicKey(pubA) + bobPrivate.GeneratePublicKey(pubB) - if !bytes.Equal(pubA.Export(), expPubA.Export()) { - t.Fatalf("unexpected value of public key A") + got := make([]byte, expPubA.Size()) + exp := make([]byte, expPubA.Size()) + pubA.Export(got) + expPubA.Export(exp) + if !bytes.Equal(got, exp) { + t.Fatalf("unexpected value of public key A\ngot [%X]\nexp [%X]", got, exp) } - if !bytes.Equal(pubB.Export(), expPubB.Export()) { - t.Fatalf("unexpected value of public key B") + + got = make([]byte, expPubB.Size()) + exp = make([]byte, expPubB.Size()) + pubB.Export(got) + expPubB.Export(exp) + if !bytes.Equal(got, exp) { + t.Fatalf("unexpected value of public key B\ngot [%X]\nexp [%X]", got, exp) } } -func testRoundtrip(t testing.TB, id uint8) { +func testRoundtrip(t *testing.T, v sidhVec) { var err error - - prvA := NewPrivateKey(id, KeyVariant_SIDH_A) - prvB := NewPrivateKey(id, KeyVariant_SIDH_B) + pubA := NewPublicKey(v.id, KeyVariantSidhA) + pubB := NewPublicKey(v.id, KeyVariantSidhB) + prvA := NewPrivateKey(v.id, KeyVariantSidhA) + prvB := NewPrivateKey(v.id, KeyVariantSidhB) + s1 := make([]byte, common.Params(v.id).SharedSecretSize) + s2 := make([]byte, common.Params(v.id).SharedSecretSize) // Generate private keys err = prvA.Generate(rand.Reader) - checkErr(t, err, "key generation failed") + CheckNoErr(t, err, "key generation failed") err = prvB.Generate(rand.Reader) - checkErr(t, err, "key generation failed") + CheckNoErr(t, err, "key generation failed") // Generate public keys - pubA := prvA.GeneratePublicKey() - pubB := prvB.GeneratePublicKey() + prvA.GeneratePublicKey(pubA) + prvB.GeneratePublicKey(pubB) // Derive shared secret - s1, err := DeriveSecret(prvB, pubA) - checkErr(t, err, "") - - s2, err := DeriveSecret(prvA, pubB) - checkErr(t, err, "") + prvB.DeriveSecret(s1, pubA) + prvA.DeriveSecret(s2, pubB) if !bytes.Equal(s1[:], s2[:]) { - t.Fatalf("Tthe two shared keys: \n%X, \n%X do not match", s1, s2) + t.Fatalf("Two shared keys do not match:\ns1 [%X]\ns2 [%X]", s1, s2) } } -func testKeyAgreement(t testing.TB, id uint8, pkA, prA, pkB, prB string) { - var e error +func testKeyAgreement(t *testing.T, v sidhVec) { + var err error + s1 := make([]byte, common.Params(v.id).SharedSecretSize) + s2 := make([]byte, common.Params(v.id).SharedSecretSize) // KeyPairs - alicePublic := convToPub(pkA, KeyVariant_SIDH_A, id) - bobPublic := convToPub(pkB, KeyVariant_SIDH_B, id) - alicePrivate := convToPrv(prA, KeyVariant_SIDH_A, id) - bobPrivate := convToPrv(prB, KeyVariant_SIDH_B, id) + alicePublic := convToPub(v.PkA, KeyVariantSidhA, v.id) + bobPublic := convToPub(v.PkB, KeyVariantSidhB, v.id) + alicePrivate := convToPrv(v.PrA, KeyVariantSidhA, v.id) + bobPrivate := convToPrv(v.PrB, KeyVariantSidhB, v.id) // Do actual test - s1, e := DeriveSecret(bobPrivate, alicePublic) - checkErr(t, e, "derivation s1") - s2, e := DeriveSecret(alicePrivate, bobPublic) - checkErr(t, e, "derivation s1") + bobPrivate.DeriveSecret(s1, alicePublic) + alicePrivate.DeriveSecret(s2, bobPublic) if !bytes.Equal(s1[:], s2[:]) { - t.Fatalf("two shared keys: %d, %d do not match", s1, s2) + t.Fatalf("two shared keys do not match\ngot [%X]\nexp [%X]", s1, s2) } // Negative case - dec, e := hex.DecodeString(tdata[id].PkA) - if e != nil { - t.FailNow() - } + dec, err := hex.DecodeString(v.PkA) + CheckNoErr(t, err, "decoding failed") + dec[0] = ^dec[0] - e = alicePublic.Import(dec) - if e != nil { - t.FailNow() - } - - s1, e = DeriveSecret(bobPrivate, alicePublic) - checkErr(t, e, "derivation of s1 failed") - s2, e = DeriveSecret(alicePrivate, bobPublic) - checkErr(t, e, "derivation of s2 failed") + err = alicePublic.Import(dec) + CheckNoErr(t, err, "import failed") + bobPrivate.DeriveSecret(s1, alicePublic) + alicePrivate.DeriveSecret(s2, bobPublic) if bytes.Equal(s1[:], s2[:]) { - t.Fatalf("The two shared keys: %d, %d match", s1, s2) + t.Fatalf("DeriveSecret produces wrong results. The two shared keys match, but they shouldn't") } } -func testImportExport(t testing.TB, id uint8) { +func testImportExport(t *testing.T, v sidhVec) { var err error - a := NewPublicKey(id, KeyVariant_SIDH_A) - b := NewPublicKey(id, KeyVariant_SIDH_B) + a := NewPublicKey(v.id, KeyVariantSidhA) + b := NewPublicKey(v.id, KeyVariantSidhB) // Import keys - a_hex, err := hex.DecodeString(tdata[id].PkA) - checkErr(t, err, "invalid hex-number provided") + aHex, err := hex.DecodeString(v.PkA) + CheckNoErr(t, err, "invalid hex-number provided") - err = a.Import(a_hex) - checkErr(t, err, "import failed") + err = a.Import(aHex) + CheckNoErr(t, err, "import failed") - b_hex, err := hex.DecodeString(tdata[id].PkB) - checkErr(t, err, "invalid hex-number provided") + bHex, err := hex.DecodeString(v.PkB) + CheckNoErr(t, err, "invalid hex-number provided") - err = b.Import(b_hex) - checkErr(t, err, "import failed") + err = b.Import(bHex) + CheckNoErr(t, err, "import failed") + + aBytes := make([]byte, a.Size()) + bBytes := make([]byte, b.Size()) + a.Export(aBytes) + b.Export(bBytes) // Export and check if same - if !bytes.Equal(b.Export(), b_hex) || !bytes.Equal(a.Export(), a_hex) { + if !bytes.Equal(bBytes, bHex) || !bytes.Equal(aBytes, aHex) { t.Fatalf("export/import failed") } - if (len(b.Export()) != b.Size()) || (len(a.Export()) != a.Size()) { + if (len(bBytes) != b.Size()) || (len(aBytes) != a.Size()) { t.Fatalf("wrong size of exported keys") } + + // Ensure that public key is unchanged after it is exported + aBytes2 := make([]byte, a.Size()) + bBytes2 := make([]byte, b.Size()) + a.Export(aBytes2) + b.Export(bBytes2) + if !bytes.Equal(aBytes, aBytes2) || !bytes.Equal(bBytes, bBytes2) { + t.Fatalf("Second export doesn't match first export") + } } -func testPrivateKeyBelowMax(t testing.TB, id uint8) { - params := Params(id) - for variant, keySz := range map[KeyVariant]*DomainParams{ - KeyVariant_SIDH_A: ¶ms.A, - KeyVariant_SIDH_B: ¶ms.B} { - - func(v KeyVariant, dp *DomainParams) { +func testPrivateKeyBelowMax(t *testing.T, vec sidhVec) { + for variant, keySz := range map[KeyVariant]*common.DomainParams{ + KeyVariantSidhA: &common.Params(vec.id).A, + KeyVariantSidhB: &common.Params(vec.id).B} { + func(v KeyVariant, dp *common.DomainParams) { var blen = int(dp.SecretByteLen) - var prv = NewPrivateKey(id, v) + var prv = NewPrivateKey(vec.id, v) + var secretBytes = make([]byte, prv.Size()) // Calculate either (2^e2 - 1) or (2^s - 1); where s=ceil(log_2(3^e3))) maxSecertVal := big.NewInt(int64(dp.SecretBitLen)) @@ -276,11 +313,11 @@ func testPrivateKeyBelowMax(t testing.TB, id uint8) { // Do same test 1000 times for i := 0; i < 1000; i++ { err := prv.Generate(rand.Reader) - checkErr(t, err, "Private key generation") + CheckNoErr(t, err, "Private key generation") // Convert to big-endian, as that's what expected by (*Int)SetBytes() - secretBytes := prv.Export() - for i := 0; i < int(blen/2); i++ { + prv.Export(secretBytes) + for i := 0; i < blen/2; i++ { tmp := secretBytes[i] ^ secretBytes[blen-i-1] secretBytes[i] = tmp ^ secretBytes[i] secretBytes[blen-i-1] = tmp ^ secretBytes[blen-i-1] @@ -295,149 +332,282 @@ func testPrivateKeyBelowMax(t testing.TB, id uint8) { } } -func TestKeyAgreementP751(t *testing.T) { - for id, val := range tdata { - fmt.Printf("\tTesting: %s\n", val.name) - testKeyAgreement(t, id, tdata[id].PkA, tdata[id].PrA, tdata[id].PkB, tdata[id].PrB) - } -} - func TestKeyAgreementP751_AliceEvenNumber(t *testing.T) { // even alice - prE := "C09957CC83045FB4C3726384D784476ACB6FFD92E5B15B3C2D451BA063F1BD4CED8FBCF682A98DD0954D37BCAF730F" - pkE := "8A2DE6FD963C475F7829B689C8B8306FC0917A39EBBC35CA171546269A85698FEC0379E2E1A3C567BE1B8EF5639F81F304889737E6CC444DBED4579DB204DC8C7928F5CBB1ECDD682A1B5C48C0DAF34208C06BF201BE4E6063B1BFDC42413B0537F8E76BEE645C1A24118301BAB17EB8D6E0F283BCB16EFB833E4BB3463953C93165A0DDAC55B385059F27FF7228486D0A733812C81C792BE9EC3A16A5DB0EB099EEA76AC0E59612251A3AD19F7CC567DA2AEBD7733171F48E471D17648692355164E27B515D2A47D7BA34B3B48A047BE7C09C4ABEE2FCC9ACA7396C8A8C9E73E29533FC7369094DFA7988778E55E53F309922C6E233F8F9C7936C3D29CEA640406FCA06450AA1978FF39F227BF06B1E072F1763447C6F513B23CDF3B0EC0379070AEE5A02D9AD8E0EB023461D631F4A9643A4C79921334945F6B33DDFC11D9703BD06B047B4DA404AB12EFD2C3A49E5C42D10DA063352748B21DE41C32A5693FE1C0DCAB111F4990CD58BECADB1892EE7A7E99C9DB4DA4E69C96E57138B99038BC9B877ECE75914EFB98DD08B9E4A2DCCB948A8F7D2F26678A9952BA0EFAB1E9CF6E51B557480DEC2BA30DE0FE4AFE30A6B30765EE75EF64F678316D81C72755AD2CFA0B8C7706B07BFA52FBC3DB84EF9E79796C0089305B1E13C78660779E0FF2A13820CE141104F976B1678990F85B2D3D2B89CD5BC4DD52603A5D24D3EFEDA44BAA0F38CDB75A220AF45EAB70F2799875D435CE50FC6315EDD4BB7AA7260AFD7CD0561B69B4FA3A817904322661C3108DA24" - testKeyAgreement(t, FP_751, pkE, prE, tdata[FP_751].PkB, tdata[FP_751].PrB) + v := tdataSidh[Fp751] + v.PkA = "FDED78E9F490CB518BD6357E18FEEB63FFEFEBE907338B3ABCA74A7E590DBF79" + + "0C732AB9E3778244608CD563064BDF6AAEF511CEAF07C702309ADAA7EBEBC6B3" + + "D7B00F5C02FB2FEDA763B2D695FD27F93F45D3AC58C2F0524A942D6DE407B651" + + "1854A1D974F11A8686CF8AD675A081F4B668F3C6617029AA33FD597C8910AB37" + + "F71DBE004A3FF8442C4B65DE51201DFAE6F9DC20FDE5B998D19C23589437229D" + + "724B4378602321F247276E7B4E441383C9BE6D277A127362D9C9FB68A41C5F5B" + + "9D2BA63FA790D62315DECF5049F0476A43D30BC1E8A36047C8EE0DA9E0A3937E" + + "BDF52A91BC53266A82CBF2CEAB227CB6D5075B486679CA7701F6F35C53499B45" + + "A451CE37C57B9BB1276142F495B83D987BD4B62E78E3084DCF3EB906D19DFA8F" + + "819DFC7FDF104C1A01CCF8D933B91EBD72CDE83A502B1FB0A5DF782BC7085766" + + "AE795123903A2D30F0F79073D27CF71BA4C9D3CA86512842AA8B5AEB729C78B1" + + "E15392E20A6043C05F88F6F412C3C9FE14F8FAAE8B8482514822162F93E81615" + + "BDD77363F872D0506FFDC1809C165A5C8A19F8EA0254D73E08202A6FF3AF43CF" + + "A7EC9B137AE003A19440DCE2EF3CFC99080F75E683AF6D0E25DF55C60B2A8013" + + "FA3D59828D31C2360DF83E202FB48AFAA65AF7279137E827B80E761FA49B842A" + + "A70FD4E77B284A14B8E28C8B11B389E1160DD9877C8D5A5A1471E605F1848369" + + "3F7578B3733DDEE117227E35B1765FEBB765B340A084E8D99176C0837099C864" + + "C71C864842D3E9B58CB870AD45F3B6BE476FEB6D" + v.PrA = "C09957CC83045FB4C3726384D784476ACB6FFD92E5B15B3C2D451BA063F1BD4CE" + + "D8FBCF682A98DD0954D37BCAF730F" + testKeyAgreement(t, v) } /* ------------------------------------------------------------------------- - Wrappers for 'testing' module + Wrappers for 'testing' SIDH -------------------------------------------------------------------------*/ -func TestKeygen(t *testing.T) { Do(testKeygen, t) } -func TestRoundtrip(t *testing.T) { Do(testRoundtrip, t) } -func TestImportExport(t *testing.T) { Do(testImportExport, t) } -func TestPrivateKeyBelowMax(t *testing.T) { Do(testPrivateKeyBelowMax, t) } +func testSidhVec(t *testing.T, m *map[uint8]sidhVec, f func(t *testing.T, v sidhVec)) { + for i := range *m { + v := (*m)[i] + t.Run(v.name, func(t *testing.T) { f(t, v) }) + } +} +func TestKeygen(t *testing.T) { testSidhVec(t, &tdataSidh, testKeygen) } +func TestRoundtrip(t *testing.T) { testSidhVec(t, &tdataSidh, testRoundtrip) } +func TestImportExport(t *testing.T) { testSidhVec(t, &tdataSidh, testImportExport) } +func TestKeyAgreement(t *testing.T) { testSidhVec(t, &tdataSidh, testKeyAgreement) } +func TestPrivateKeyBelowMax(t *testing.T) { testSidhVec(t, &tdataSidh, testPrivateKeyBelowMax) } /* ------------------------------------------------------------------------- Benchmarking -------------------------------------------------------------------------*/ func BenchmarkSidhKeyAgreementP751(b *testing.B) { // KeyPairs - alicePublic := convToPub(tdata[FP_751].PkA, KeyVariant_SIDH_A, FP_751) - bobPublic := convToPub(tdata[FP_751].PkB, KeyVariant_SIDH_B, FP_751) - alicePrivate := convToPrv(tdata[FP_751].PrA, KeyVariant_SIDH_A, FP_751) - bobPrivate := convToPrv(tdata[FP_751].PrB, KeyVariant_SIDH_B, FP_751) + alicePublic := convToPub(tdataSidh[Fp751].PkA, KeyVariantSidhA, Fp751) + bobPublic := convToPub(tdataSidh[Fp751].PkB, KeyVariantSidhB, Fp751) + alicePrivate := convToPrv(tdataSidh[Fp751].PrA, KeyVariantSidhA, Fp751) + bobPrivate := convToPrv(tdataSidh[Fp751].PrB, KeyVariantSidhB, Fp751) + var ss [2 * 94]byte for i := 0; i < b.N; i++ { // Derive shared secret - DeriveSecret(bobPrivate, alicePublic) - DeriveSecret(alicePrivate, bobPublic) + bobPrivate.DeriveSecret(ss[:], alicePublic) + alicePrivate.DeriveSecret(ss[:], bobPublic) } } func BenchmarkSidhKeyAgreementP503(b *testing.B) { // KeyPairs - alicePublic := convToPub(tdata[FP_503].PkA, KeyVariant_SIDH_A, FP_503) - bobPublic := convToPub(tdata[FP_503].PkB, KeyVariant_SIDH_B, FP_503) - alicePrivate := convToPrv(tdata[FP_503].PrA, KeyVariant_SIDH_A, FP_503) - bobPrivate := convToPrv(tdata[FP_503].PrB, KeyVariant_SIDH_B, FP_503) + alicePublic := convToPub(tdataSidh[Fp503].PkA, KeyVariantSidhA, Fp503) + bobPublic := convToPub(tdataSidh[Fp503].PkB, KeyVariantSidhB, Fp503) + alicePrivate := convToPrv(tdataSidh[Fp503].PrA, KeyVariantSidhA, Fp503) + bobPrivate := convToPrv(tdataSidh[Fp503].PrB, KeyVariantSidhB, Fp503) + var ss [2 * 63]byte for i := 0; i < b.N; i++ { // Derive shared secret - DeriveSecret(bobPrivate, alicePublic) - DeriveSecret(alicePrivate, bobPublic) + bobPrivate.DeriveSecret(ss[:], alicePublic) + alicePrivate.DeriveSecret(ss[:], bobPublic) + } +} + +func BenchmarkSidhKeyAgreementP434(b *testing.B) { + // KeyPairs + alicePublic := convToPub(tdataSidh[Fp434].PkA, KeyVariantSidhA, Fp434) + bobPublic := convToPub(tdataSidh[Fp434].PkB, KeyVariantSidhB, Fp434) + alicePrivate := convToPrv(tdataSidh[Fp434].PrA, KeyVariantSidhA, Fp434) + bobPrivate := convToPrv(tdataSidh[Fp434].PrB, KeyVariantSidhB, Fp434) + var ss [2 * 63]byte + + for i := 0; i < b.N; i++ { + // Derive shared secret + bobPrivate.DeriveSecret(ss[:], alicePublic) + alicePrivate.DeriveSecret(ss[:], bobPublic) } } func BenchmarkAliceKeyGenPrvP751(b *testing.B) { - prv := NewPrivateKey(FP_751, KeyVariant_SIDH_A) + prv := NewPrivateKey(Fp751, KeyVariantSidhA) for n := 0; n < b.N; n++ { - prv.Generate(rand.Reader) + _ = prv.Generate(rand.Reader) } } func BenchmarkAliceKeyGenPrvP503(b *testing.B) { - prv := NewPrivateKey(FP_503, KeyVariant_SIDH_A) + prv := NewPrivateKey(Fp503, KeyVariantSidhA) for n := 0; n < b.N; n++ { - prv.Generate(rand.Reader) + _ = prv.Generate(rand.Reader) + } +} + +func BenchmarkAliceKeyGenPrvP434(b *testing.B) { + prv := NewPrivateKey(Fp434, KeyVariantSidhA) + for n := 0; n < b.N; n++ { + _ = prv.Generate(rand.Reader) } } func BenchmarkBobKeyGenPrvP751(b *testing.B) { - prv := NewPrivateKey(FP_751, KeyVariant_SIDH_B) + prv := NewPrivateKey(Fp751, KeyVariantSidhB) for n := 0; n < b.N; n++ { - prv.Generate(rand.Reader) + _ = prv.Generate(rand.Reader) } } func BenchmarkBobKeyGenPrvP503(b *testing.B) { - prv := NewPrivateKey(FP_503, KeyVariant_SIDH_B) + prv := NewPrivateKey(Fp503, KeyVariantSidhB) for n := 0; n < b.N; n++ { - prv.Generate(rand.Reader) + _ = prv.Generate(rand.Reader) + } +} + +func BenchmarkBobKeyGenPrvP434(b *testing.B) { + prv := NewPrivateKey(Fp434, KeyVariantSidhB) + for n := 0; n < b.N; n++ { + _ = prv.Generate(rand.Reader) } } func BenchmarkAliceKeyGenPubP751(b *testing.B) { - prv := NewPrivateKey(FP_751, KeyVariant_SIDH_A) - prv.Generate(rand.Reader) + prv := NewPrivateKey(Fp751, KeyVariantSidhA) + pub := NewPublicKey(Fp751, KeyVariantSidhA) + _ = prv.Generate(rand.Reader) for n := 0; n < b.N; n++ { - prv.GeneratePublicKey() + prv.GeneratePublicKey(pub) } } func BenchmarkAliceKeyGenPubP503(b *testing.B) { - prv := NewPrivateKey(FP_503, KeyVariant_SIDH_A) - prv.Generate(rand.Reader) + prv := NewPrivateKey(Fp503, KeyVariantSidhA) + pub := NewPublicKey(Fp503, KeyVariantSidhA) + _ = prv.Generate(rand.Reader) for n := 0; n < b.N; n++ { - prv.GeneratePublicKey() + prv.GeneratePublicKey(pub) + } +} + +func BenchmarkAliceKeyGenPubP434(b *testing.B) { + prv := NewPrivateKey(Fp434, KeyVariantSidhA) + pub := NewPublicKey(Fp434, KeyVariantSidhA) + _ = prv.Generate(rand.Reader) + for n := 0; n < b.N; n++ { + prv.GeneratePublicKey(pub) } } func BenchmarkBobKeyGenPubP751(b *testing.B) { - prv := NewPrivateKey(FP_751, KeyVariant_SIDH_B) - prv.Generate(rand.Reader) + prv := NewPrivateKey(Fp751, KeyVariantSidhB) + pub := NewPublicKey(Fp751, KeyVariantSidhB) + _ = prv.Generate(rand.Reader) for n := 0; n < b.N; n++ { - prv.GeneratePublicKey() + prv.GeneratePublicKey(pub) } } func BenchmarkBobKeyGenPubP503(b *testing.B) { - prv := NewPrivateKey(FP_503, KeyVariant_SIDH_B) - prv.Generate(rand.Reader) + prv := NewPrivateKey(Fp503, KeyVariantSidhB) + pub := NewPublicKey(Fp503, KeyVariantSidhB) + _ = prv.Generate(rand.Reader) for n := 0; n < b.N; n++ { - prv.GeneratePublicKey() + prv.GeneratePublicKey(pub) + } +} + +func BenchmarkBobKeyGenPubP434(b *testing.B) { + prv := NewPrivateKey(Fp434, KeyVariantSidhB) + pub := NewPublicKey(Fp434, KeyVariantSidhB) + _ = prv.Generate(rand.Reader) + for n := 0; n < b.N; n++ { + prv.GeneratePublicKey(pub) } } func BenchmarkSharedSecretAliceP751(b *testing.B) { - aPr := convToPrv(tdata[FP_751].PrA, KeyVariant_SIDH_A, FP_751) - bPk := convToPub(tdata[FP_751].PkB, KeyVariant_SIDH_B, FP_751) + aPr := convToPrv(tdataSidh[Fp751].PrA, KeyVariantSidhA, Fp751) + bPk := convToPub(tdataSidh[Fp751].PkB, KeyVariantSidhB, Fp751) + var ss [2 * 94]byte for n := 0; n < b.N; n++ { - DeriveSecret(aPr, bPk) + aPr.DeriveSecret(ss[:], bPk) } } func BenchmarkSharedSecretAliceP503(b *testing.B) { - aPr := convToPrv(tdata[FP_503].PrA, KeyVariant_SIDH_A, FP_503) - bPk := convToPub(tdata[FP_503].PkB, KeyVariant_SIDH_B, FP_503) + aPr := convToPrv(tdataSidh[Fp503].PrA, KeyVariantSidhA, Fp503) + bPk := convToPub(tdataSidh[Fp503].PkB, KeyVariantSidhB, Fp503) + var ss [2 * 63]byte for n := 0; n < b.N; n++ { - DeriveSecret(aPr, bPk) + aPr.DeriveSecret(ss[:], bPk) + } +} + +func BenchmarkSharedSecretAliceP434(b *testing.B) { + aPr := convToPrv(tdataSidh[Fp434].PrA, KeyVariantSidhA, Fp434) + bPk := convToPub(tdataSidh[Fp434].PkB, KeyVariantSidhB, Fp434) + var ss [2 * 63]byte + for n := 0; n < b.N; n++ { + aPr.DeriveSecret(ss[:], bPk) } } func BenchmarkSharedSecretBobP751(b *testing.B) { // m_B = 3*randint(0,3^238) - aPk := convToPub(tdata[FP_751].PkA, KeyVariant_SIDH_A, FP_751) - bPr := convToPrv(tdata[FP_751].PrB, KeyVariant_SIDH_B, FP_751) + aPk := convToPub(tdataSidh[Fp751].PkA, KeyVariantSidhA, Fp751) + bPr := convToPrv(tdataSidh[Fp751].PrB, KeyVariantSidhB, Fp751) + var ss [2 * 94]byte for n := 0; n < b.N; n++ { - DeriveSecret(bPr, aPk) + bPr.DeriveSecret(ss[:], aPk) } } func BenchmarkSharedSecretBobP503(b *testing.B) { // m_B = 3*randint(0,3^238) - aPk := convToPub(tdata[FP_503].PkA, KeyVariant_SIDH_A, FP_503) - bPr := convToPrv(tdata[FP_503].PrB, KeyVariant_SIDH_B, FP_503) + aPk := convToPub(tdataSidh[Fp503].PkA, KeyVariantSidhA, Fp503) + bPr := convToPrv(tdataSidh[Fp503].PrB, KeyVariantSidhB, Fp503) + var ss [2 * 63]byte for n := 0; n < b.N; n++ { - DeriveSecret(bPr, aPk) + bPr.DeriveSecret(ss[:], aPk) } } + +func BenchmarkSharedSecretBobP434(b *testing.B) { + // m_B = 3*randint(0,3^238) + aPk := convToPub(tdataSidh[Fp434].PkA, KeyVariantSidhA, Fp434) + bPr := convToPrv(tdataSidh[Fp434].PrB, KeyVariantSidhB, Fp434) + var ss [2 * 63]byte + for n := 0; n < b.N; n++ { + bPr.DeriveSecret(ss[:], aPk) + } +} + +// Examples + +func ExamplePrivateKey() { + // import "github.com/henrydcase/nobs/dh/sidh" + + // Allice's key pair + prvA := NewPrivateKey(Fp503, KeyVariantSidhA) + pubA := NewPublicKey(Fp503, KeyVariantSidhA) + // Bob's key pair + prvB := NewPrivateKey(Fp503, KeyVariantSidhB) + pubB := NewPublicKey(Fp503, KeyVariantSidhB) + // Generate keypair for Allice + err := prvA.Generate(rand.Reader) + if err != nil { + fmt.Print(err) + } + prvA.GeneratePublicKey(pubA) + // Generate keypair for Bob + err = prvB.Generate(rand.Reader) + if err != nil { + fmt.Print(err) + } + prvB.GeneratePublicKey(pubB) + // Buffers storing shared secret + ssA := make([]byte, prvA.SharedSecretSize()) + ssB := make([]byte, prvA.SharedSecretSize()) + // Allice calculates shared secret with hers private + // key and Bob's public key + prvA.DeriveSecret(ssA[:], pubB) + // Bob calculates shared secret with hers private + // key and Allice's public key + prvB.DeriveSecret(ssB[:], pubA) + // Check if ssA == ssB + fmt.Printf("%t\n", bytes.Equal(ssA, ssB)) + // Output: + // true +} diff --git a/dh/sidh/sike.go b/dh/sidh/sike.go new file mode 100644 index 0000000..0d77ec4 --- /dev/null +++ b/dh/sidh/sike.go @@ -0,0 +1,262 @@ +package sidh + +import ( + "crypto/subtle" + "errors" + "io" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" + "github.com/henrydcase/nobs/internal/shake" +) + +// SIKE KEM interface. +type KEM struct { + allocated bool + rng io.Reader + msg []byte + secretBytes []byte + params *common.SidhParams + shake shake.Shake +} + +// NewSike434 instantiates SIKE/p434 KEM. +func NewSike434(rng io.Reader) *KEM { + var c KEM + c.Allocate(Fp434, rng) + return &c +} + +// NewSike503 instantiates SIKE/p503 KEM. +func NewSike503(rng io.Reader) *KEM { + var c KEM + c.Allocate(Fp503, rng) + return &c +} + +// NewSike751 instantiates SIKE/p751 KEM. +func NewSike751(rng io.Reader) *KEM { + var c KEM + c.Allocate(Fp751, rng) + return &c +} + +// Allocate allocates KEM object for multiple SIKE operations. The rng +// must be cryptographically secure PRNG. +func (c *KEM) Allocate(id uint8, rng io.Reader) { + c.rng = rng + c.params = common.Params(id) + c.msg = make([]byte, c.params.MsgLen) + c.secretBytes = make([]byte, c.params.A.SecretByteLen) + c.shake = shake.NewShake256() + c.allocated = true +} + +// Encapsulate receives the public key and generates SIKE ciphertext and shared secret. +// The generated ciphertext is used for authentication. +// Error is returned in case PRNG fails. Function panics in case wrongly formated +// input was provided. +func (c *KEM) Encapsulate(ciphertext, secret []byte, pub *PublicKey) error { + if !c.allocated { + panic("KEM unallocated") + } + + if KeyVariantSike != pub.keyVariant { + panic("Wrong type of public key") + } + + if len(secret) < c.SharedSecretSize() { + panic("shared secret buffer to small") + } + + if len(ciphertext) < c.CiphertextSize() { + panic("ciphertext buffer to small") + } + + // Generate ephemeral value + _, err := io.ReadFull(c.rng, c.msg[:]) + if err != nil { + return err + } + + var buf [3 * common.MaxSharedSecretBsz]byte + var skA = PrivateKey{ + key: key{ + params: c.params, + keyVariant: KeyVariantSidhA}, + Scalar: c.secretBytes} + var pkA = NewPublicKey(c.params.ID, KeyVariantSidhA) + + pub.Export(buf[:]) + c.shake.Reset() + _, _ = c.shake.Write(c.msg) + _, _ = c.shake.Write(buf[:3*c.params.SharedSecretSize]) + _, _ = c.shake.Read(skA.Scalar) + + // Ensure bitlength is not bigger then to 2^e2-1 + skA.Scalar[len(skA.Scalar)-1] &= (1 << (c.params.A.SecretBitLen % 8)) - 1 + skA.GeneratePublicKey(pkA) + c.generateCiphertext(ciphertext, &skA, pkA, pub, c.msg[:]) + + // K = H(msg||(c0||c1)) + c.shake.Reset() + _, _ = c.shake.Write(c.msg) + _, _ = c.shake.Write(ciphertext) + _, _ = c.shake.Read(secret[:c.SharedSecretSize()]) + return nil +} + +// Decapsulate given the keypair and ciphertext as inputs, Decapsulate outputs a shared +// secret if plaintext verifies correctly, otherwise function outputs random value. +// Decapsulation may panic in case input is wrongly formated, in particular, size of +// the 'ciphertext' must be exactly equal to c.CiphertextSize(). +func (c *KEM) Decapsulate(secret []byte, prv *PrivateKey, pub *PublicKey, ciphertext []byte) error { + if !c.allocated { + panic("KEM unallocated") + } + + if KeyVariantSike != pub.keyVariant { + panic("Wrong type of public key") + } + + if pub.keyVariant != prv.keyVariant { + panic("Public and private key are of different type") + } + + if len(secret) < c.SharedSecretSize() { + panic("shared secret buffer to small") + } + + if len(ciphertext) != c.CiphertextSize() { + panic("ciphertext buffer to small") + } + + var m [common.MaxMsgBsz]byte + var r [common.MaxSidhPrivateKeyBsz]byte + var pkBytes [3 * common.MaxSharedSecretBsz]byte + var skA = PrivateKey{ + key: key{ + params: c.params, + keyVariant: KeyVariantSidhA}, + Scalar: c.secretBytes} + var pkA = NewPublicKey(c.params.ID, KeyVariantSidhA) + c1Len, err := c.decrypt(m[:], prv, ciphertext) + if err != nil { + return err + } + + // r' = G(m'||pub) + pub.Export(pkBytes[:]) + c.shake.Reset() + _, _ = c.shake.Write(m[:c1Len]) + _, _ = c.shake.Write(pkBytes[:3*c.params.SharedSecretSize]) + _, _ = c.shake.Read(r[:c.params.A.SecretByteLen]) + // Ensure bitlength is not bigger than 2^e2-1 + r[c.params.A.SecretByteLen-1] &= (1 << (c.params.A.SecretBitLen % 8)) - 1 + + err = skA.Import(r[:c.params.A.SecretByteLen]) + if err != nil { + return err + } + skA.GeneratePublicKey(pkA) + pkA.Export(pkBytes[:]) + + // S is chosen at random when generating a key and unknown to other party. It is + // important that S is unpredictable to the other party. Without this check, would + // be possible to recover a secret, by providing series of invalid ciphertexts. + // + // See more details in "On the security of supersingular isogeny cryptosystems" + // (S. Galbraith, et al., 2016, ePrint #859). + mask := subtle.ConstantTimeCompare(pkBytes[:c.params.PublicKeySize], ciphertext[:pub.params.PublicKeySize]) + common.Cpick(mask, m[:c1Len], m[:c1Len], prv.S) + c.shake.Reset() + _, _ = c.shake.Write(m[:c1Len]) + _, _ = c.shake.Write(ciphertext) + _, _ = c.shake.Read(secret[:c.SharedSecretSize()]) + return nil +} + +// Resets internal state of KEM. Function should be used +// after Allocate and between subsequent calls to Encapsulate +// and/or Decapsulate. +func (c *KEM) Reset() { + for i := range c.msg { + c.msg[i] = 0 + } + + for i := range c.secretBytes { + c.secretBytes[i] = 0 + } +} + +// Returns size of resulting ciphertext. +func (c *KEM) CiphertextSize() int { + return c.params.CiphertextSize +} + +// Returns size of resulting shared secret. +func (c *KEM) SharedSecretSize() int { + return c.params.KemSize +} + +func (c *KEM) generateCiphertext(ctext []byte, skA *PrivateKey, pkA, pkB *PublicKey, ptext []byte) { + var n [common.MaxMsgBsz]byte + var j [common.MaxSharedSecretBsz]byte + var ptextLen = skA.params.MsgLen + + skA.DeriveSecret(j[:], pkB) + c.shake.Reset() + _, _ = c.shake.Write(j[:skA.params.SharedSecretSize]) + _, _ = c.shake.Read(n[:ptextLen]) + for i := range ptext { + n[i] ^= ptext[i] + } + + pkA.Export(ctext) + copy(ctext[pkA.Size():], n[:ptextLen]) +} + +// encrypt uses SIKE public key to encrypt plaintext. Requires cryptographically secure +// PRNG. Returns ciphertext in case encryption succeeds. Returns error in case PRNG fails +// or wrongly formated input was provided. +func (c *KEM) encrypt(ctext []byte, rng io.Reader, pub *PublicKey, ptext []byte) error { + var ptextLen = len(ptext) + // c1 must be security level + 64 bits (see [SIKE] 1.4 and 4.3.3) + if ptextLen != pub.params.KemSize { + return errors.New("unsupported message length") + } + + skA := NewPrivateKey(pub.params.ID, KeyVariantSidhA) + pkA := NewPublicKey(pub.params.ID, KeyVariantSidhA) + err := skA.Generate(rng) + if err != nil { + return err + } + + skA.GeneratePublicKey(pkA) + c.generateCiphertext(ctext, skA, pkA, pub, ptext) + return nil +} + +// decrypt uses SIKE private key to decrypt ciphertext. Returns plaintext in case +// decryption succeeds or error in case unexptected input was provided. +// Constant time. +func (c *KEM) decrypt(n []byte, prv *PrivateKey, ctext []byte) (int, error) { + var c1Len int + var j [common.MaxSharedSecretBsz]byte + var pkLen = prv.params.PublicKeySize + + // ctext is a concatenation of (ciphertext = pubkey_A || c1) + // it must be security level + 64 bits (see [SIKE] 1.4 and 4.3.3) + // Lengths has been already checked by Decapsulate() + c1Len = len(ctext) - pkLen + c0 := NewPublicKey(prv.params.ID, KeyVariantSidhA) + err := c0.Import(ctext[:pkLen]) + prv.DeriveSecret(j[:], c0) + c.shake.Reset() + _, _ = c.shake.Write(j[:prv.params.SharedSecretSize]) + _, _ = c.shake.Read(n[:c1Len]) + for i := range n[:c1Len] { + n[i] ^= ctext[pkLen+i] + } + return c1Len, err +} diff --git a/dh/sidh/sike_test.go b/dh/sidh/sike_test.go new file mode 100644 index 0000000..cfa63b1 --- /dev/null +++ b/dh/sidh/sike_test.go @@ -0,0 +1,579 @@ +package sidh + +import ( + "bufio" + "bytes" + "crypto/rand" + "encoding/hex" + "fmt" + "io" + "os" + "strings" + "testing" + + "github.com/henrydcase/nobs/dh/sidh/internal/common" + . "github.com/henrydcase/nobs/internal/test" +) + +type sikeVec struct { + id uint8 + name string + kem *KEM + KatFile string + PkB string + PrB string +} + +var tdataSike = map[uint8]sikeVec{ + Fp434: { + Fp434, "P-434", NewSike434(rand.Reader), + "testdata/PQCkemKAT_374.rsp", + "1BD0A2E81307B6F96461317DDF535ACC0E59C742627BAE60D27605E10FAF722D" + + "22A73E184CB572A12E79DCD58C6B54FB01442114CBE9010B6CAEC25D04C16C5E" + + "42540C1524C545B8C67614ED4183C9FA5BD0BE45A7F89FBC770EE8E7E5E391C7" + + "EE6F35F74C29E6D9E35B1663DA01E48E9DEB2347512D366FDE505161677055E3" + + "EF23054D276E817E2C57025DA1C10D2461F68617F2D11256EEE4E2D7DBDF6C8E" + + "34F3A0FD00C625428CB41857002159DAB94267ABE42D630C6AAA91AF837C7A67" + + "40754EA6634C45454C51B0BB4D44C3CCCCE4B32C00901CF69C008D013348379B" + + "2F9837F428A01B6173584691F2A6F3A3C4CF487D20D261B36C8CDB1BC158E2A5" + + "162A9DA4F7A97AA0879B9897E2B6891B672201F9AEFBF799C27B2587120AC586" + + "A511360926FB7DA8EBF5CB5272F396AE06608422BE9792E2CE9BEF21BF55B7EF" + + "F8DC7EC8C99910D3F800", + "4B622DE1350119C45A9F2E2EF3DC5DF56A27FCDFCDDAF58CD69B903752D68C20" + + "0934E160B234E49EDE247601"}, + Fp503: { + Fp503, "P-503", NewSike503(rand.Reader), + "testdata/PQCkemKAT_434.rsp", + "4032A90B6C036B7D2A83878AD116641AD319E420235A505F3F5C3DEC27C87A6C" + + "BA0792201D6E7B196C582D43CAF86CB2C7DEFA6598B543C946CDDF62EF9A328C" + + "8719B66BA5052231DAE13AF7D9CDEBB4ED327773C7AE0818F41AF1D28CD78B16" + + "C996232528235C8392B8FCFD925CB311B2A801B0402A90E527261EA32F2BEF67" + + "7C544908D5509B8AB7D7BF20456727AD358AD585306A0B28F6B2AA583CE8A3E0" + + "BB92D8CD55347D39D4E3C30D3D0F96EABB721A6968CDD143FE9227643CF697FB" + + "2DF0B71322B5EA1505D0DDBF70A2FD1193011F3BC18AA1E127C614B76969DCDA" + + "45A2072B519A1074FDA49F5C828450C6A007BF8D7CDDD5D2FC112119C679CA3A" + + "B16C6960B25F6C681A7DCED0F0E3901740D3DBF3A33011EB7DA460E8ADA80EE3" + + "45B2B71420950A9A803E4F11330EB91CCABB1EEE4D875A109D7724ABD201272C" + + "0B4981BDCDFA70F3430A89D2A88EEED474CF0CFAC65CE883F44B4722FA280C6F" + + "A9C4724D414B35AF69D6ECB21BFDA23BFF6B66C22C2451DC8E1C", + "7BF6938C975658AEB8B4D37CFFBDE25D97E561F36C219A0E8FE645816DBBC7ED7B57" + + "7700AE8DC3138E97A0C3F6F002065C92A0B1B8180208"}, + Fp751: { + Fp751, "P-751", NewSike751(rand.Reader), + "testdata/PQCkemKAT_644.rsp", + "E1A758EC0D418BFE86D8077B5BB169133C06C1F2A067D8B202D9D058FFC51F63" + + "FD26155A6577C74BA7F1A27E7BA51982517B923615DEB00BE408920A07831DF5" + + "978CFDDD0BF690A264353A4A16B666F90586D7F89A193CE09375D389C1379A7A" + + "528581C3ACB002CD2DC4F0FD672568FF9050BA8365C7FEFC5E6ED089B921DE68" + + "04091A0744DE3EB14D426A3F7DA215C50312617C1C2697243980D06056F2CCE8" + + "8AE7AE73C7343C0B7104C9F2870A94FED744CF6E94630514B6CEAB0E64733BB6" + + "FA67B931E5D8206010475CBE8BC587248D65D89D8CD9C8BBFA93E8B5F9EB9130" + + "773DED665D52ABBD91C4C8C255F73C0FC82501AE33330E9F308DE7177CBF83E4" + + "E26E334D7CB09019E638147FC58ED372AF660F14C194BC80E9666325C98E0F80" + + "877271D4A6BF514F603703D8A697874CD50A34D92F5AAEA84633CCF96801BD51" + + "7BF425DEE4A32AAF06684052473EA14643C3D535440FB2240A988D09F297C5A3" + + "88CB3DE60ED943F124034B90EFF611221F80F78EC124956338A105F6636B063D" + + "7E48BFBD5D614310FB97D86F122E4AE6F9DDF4977A93ED7D0CE2A94E346A1A03" + + "D3219CF21907B85A5BCDC713F93A4406A22E03B1655A66E1F6741A2F953E6FE0" + + "868B2614BABEF1943BBBCB1B66D3E7017E533EA84F291240B56AB33EF1DC3F3D" + + "E99DBF9E8BE51A0076E462BCDD825EA96D7F63C99177C305C257B31461F4C23D" + + "43115F0220409E8880BBB2468586D03461E807BE824B693874911B2B52AF06FD" + + "BDC47F5A0159729641A7C950AB9E03F2DC045135", + "0001020304050607080900010203040506070809000102030405060708090102" + + "8626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB8F" + + "AB0A7289852106E40538D3575C500201"}, +} + +// Encrypt, Decrypt, check if input/output plaintext is the same. +func testPKERoundTrip(t *testing.T, v sikeVec) { + // Message to be encrypted + var pt [common.MaxMsgBsz]byte + var params = common.Params(v.id) + var ct = make([]byte, v.kem.CiphertextSize()) + var msg = make([]byte, params.MsgLen) + for i := range msg { + msg[i] = byte(i) + } + + // Import keys + pkB := NewPublicKey(params.ID, KeyVariantSike) + skB := NewPrivateKey(params.ID, KeyVariantSike) + pkHex, err := hex.DecodeString(v.PkB) + CheckNoErr(t, err, "Test vector wrong") + skHex, err := hex.DecodeString(v.PrB) + CheckNoErr(t, err, "Test vector wrong") + err = pkB.Import(pkHex) + CheckNoErr(t, err, "Public key import failed") + err = skB.Import(skHex) + CheckNoErr(t, err, "Private key import failed") + err = v.kem.encrypt(ct, rand.Reader, pkB, msg[:]) + CheckNoErr(t, err, "PKE roundtrip - encryption failed") + ptLen, err := v.kem.decrypt(pt[:], skB, ct) + CheckNoErr(t, err, "PKE roundtrip - decription failed") + + if !bytes.Equal(pt[:ptLen], msg[:]) { + t.Errorf("Decryption failed \n got : %X\n exp : %X", pt[:ptLen], msg) + } +} + +// Generate key and check if can encrypt. +func testPKEKeyGeneration(t *testing.T, v sikeVec) { + var err error + var params = common.Params(v.id) + var pt [common.MaxMsgBsz]byte + var msg = make([]byte, params.MsgLen) + var ct = make([]byte, v.kem.CiphertextSize()) + // static buffer to ensure no overrides + var pk = NewPublicKey(v.id, KeyVariantSike) + var sk = NewPrivateKey(v.id, KeyVariantSike) + + for i := range msg { + msg[i] = byte(i) + } + + err = sk.Generate(rand.Reader) + CheckNoErr(t, err, "PKE key generation") + sk.GeneratePublicKey(pk) + + err = v.kem.encrypt(ct, rand.Reader, pk, msg[:]) + CheckNoErr(t, err, "PKE encryption") + ptLen, err := v.kem.decrypt(pt[:], sk, ct) + CheckNoErr(t, err, "PKE key decryption") + + if !bytes.Equal(pt[:ptLen], msg[:]) { + t.Fatalf("Decryption failed \n got : %X\n exp : %X", pt, msg) + } +} + +func testNegativePKE(t *testing.T, v sikeVec) { + var err error + var msg [common.MaxMsgBsz]byte + var ct = make([]byte, v.kem.CiphertextSize()) + var pk = NewPublicKey(v.id, KeyVariantSike) + var sk = NewPrivateKey(v.id, KeyVariantSike) + + // Generate key + err = sk.Generate(rand.Reader) + CheckNoErr(t, err, "key generation") + sk.GeneratePublicKey(pk) + + // bytelen(msg) - 1 + err = v.kem.encrypt(ct, rand.Reader, pk, msg[:v.kem.params.KemSize+8-1]) + CheckIsErr(t, err, "PKE encryption doesn't fail") + for _, v := range ct { + if v != 0 { + t.Fatal("Returned ciphertext must be not changed") + } + } +} + +func testKEMRoundTrip(t *testing.T, pkB, skB []byte, v sikeVec) { + // Import keys + var err error + var ssE [common.MaxSharedSecretBsz]byte + var ssD [common.MaxSharedSecretBsz]byte + var pk = NewPublicKey(v.id, KeyVariantSike) + var sk = NewPrivateKey(v.id, KeyVariantSike) + var ct = make([]byte, v.kem.CiphertextSize()) + var ssBsz = v.kem.SharedSecretSize() + + err = pk.Import(pkB) + CheckNoErr(t, err, "Public key import failed") + err = sk.Import(skB) + CheckNoErr(t, err, "Private key import failed") + + v.kem.Reset() + err = v.kem.Encapsulate(ct, ssE[:], pk) + CheckNoErr(t, err, "Encapsulation failed") + v.kem.Reset() + err = v.kem.Decapsulate(ssD[:ssBsz], sk, pk, ct) + CheckNoErr(t, err, "Decapsulation failed") + + if !bytes.Equal(ssE[:v.kem.SharedSecretSize()], ssD[:v.kem.SharedSecretSize()]) { + t.Errorf("Shared secrets from decapsulation and encapsulation differ [%s]", v.name) + } +} + +func testKEMKeyGeneration(t *testing.T, v sikeVec) { + var ssE [common.MaxSharedSecretBsz]byte + var ssD [common.MaxSharedSecretBsz]byte + var ct = make([]byte, v.kem.CiphertextSize()) + + sk := NewPrivateKey(v.id, KeyVariantSike) + pk := NewPublicKey(v.id, KeyVariantSike) + CheckNoErr(t, sk.Generate(rand.Reader), "error: key generation") + sk.GeneratePublicKey(pk) + + // calculated shared secret + v.kem.Reset() + err := v.kem.Encapsulate(ct, ssE[:], pk) + CheckNoErr(t, err, "encapsulation failed") + v.kem.Reset() + err = v.kem.Decapsulate(ssD[:v.kem.SharedSecretSize()], sk, pk, ct) + CheckNoErr(t, err, "decapsulation failed") + + if !bytes.Equal(ssE[:], ssD[:]) { + t.Fatalf("KEM failed \n encapsulated: %X\n decapsulated: %X", ssD[:], ssE[:]) + } +} + +func testNegativeKEM(t *testing.T, v sikeVec) { + var ssE [common.MaxSharedSecretBsz]byte + var ssD [common.MaxSharedSecretBsz]byte + var ssTmp [common.MaxSharedSecretBsz]byte + var ct = make([]byte, v.kem.CiphertextSize()) + var ssBsz = v.kem.SharedSecretSize() + + sk := NewPrivateKey(v.id, KeyVariantSike) + pk := NewPublicKey(v.id, KeyVariantSike) + CheckNoErr(t, sk.Generate(rand.Reader), "error: key generation") + sk.GeneratePublicKey(pk) + + v.kem.Reset() + err := v.kem.Encapsulate(ct, ssE[:], pk) + CheckNoErr(t, err, "pre-requisite for a test failed") + + // Try decapsulate too small ciphertext + v.kem.Reset() + CheckNoErr( + t, + CheckPanic(func() { _ = v.kem.Decapsulate(ssTmp[:ssBsz], sk, pk, ct[:len(ct)-2]) }), + "Decapsulation must panic if ciphertext is too small") + + ctTmp := make([]byte, len(ct)+1) + // Try decapsulate too big ciphertext + v.kem.Reset() + CheckNoErr( + t, + CheckPanic(func() { _ = v.kem.Decapsulate(ssTmp[:ssBsz], sk, pk, ctTmp) }), + "Decapsulation must panic if ciphertext is too big") + + // Change ciphertext + ct[0] = ct[0] - 1 + v.kem.Reset() + err = v.kem.Decapsulate(ssD[:ssBsz], sk, pk, ct) + CheckNoErr(t, err, "decapsulation returns error when invalid ciphertext provided") + + if bytes.Equal(ssE[:], ssD[:]) { + // no idea how this could ever happen, but it would be very bad + t.Error("critical error") + } + + // Try encapsulating with SIDH key + pkSidh := NewPublicKey(v.id, KeyVariantSidhB) + prSidh := NewPrivateKey(v.id, KeyVariantSidhB) + v.kem.Reset() + CheckNoErr( + t, + CheckPanic(func() { _ = v.kem.Encapsulate(ct, ssE[:], pkSidh) }), + "encapsulation accepts SIDH public key") + + // Try decapsulating with SIDH key + v.kem.Reset() + CheckNoErr( + t, + CheckPanic(func() { _ = v.kem.Decapsulate(ssD[:ssBsz], prSidh, pk, ct) }), + "encapsulation accepts SIDH public key") +} + +// In case invalid ciphertext is provided, SIKE's decapsulation must +// return same (but unpredictable) result for a given key. +func testNegativeKEMSameWrongResult(t *testing.T, v sikeVec) { + var ssE [common.MaxSharedSecretBsz]byte + var ssD1 [common.MaxSharedSecretBsz]byte + var ssD2 [common.MaxSharedSecretBsz]byte + var ct = make([]byte, v.kem.CiphertextSize()) + var ssBsz = v.kem.SharedSecretSize() + + sk := NewPrivateKey(v.id, KeyVariantSike) + pk := NewPublicKey(v.id, KeyVariantSike) + CheckNoErr(t, sk.Generate(rand.Reader), "error: key generation") + sk.GeneratePublicKey(pk) + + v.kem.Reset() + err := v.kem.Encapsulate(ct, ssE[:], pk) + CheckNoErr(t, err, "pre-requisite for a test failed") + + // make ciphertext wrong + ct[0] = ct[0] - 1 + v.kem.Reset() + err = v.kem.Decapsulate(ssD1[:ssBsz], sk, pk, ct) + CheckNoErr(t, err, "pre-requisite for a test failed") + + // change secret keysecond decapsulation must be done with same, but imported private key + var expSk [common.MaxSikePrivateKeyBsz]byte + sk.Export(expSk[:]) + + // create new private key + sk = NewPrivateKey(v.id, KeyVariantSike) + CheckNoErr(t, sk.Import(expSk[:sk.Size()]), "import failed") + + // try decapsulating again. + v.kem.Reset() + err = v.kem.Decapsulate(ssD2[:ssBsz], sk, pk, ct) + CheckNoErr(t, err, "pre-requisite for a test failed") + + // ssD1 must be same as ssD2 + if !bytes.Equal(ssD1[:], ssD2[:]) { + t.Error("decapsulation is insecure") + } + + // ssD1 and ssD2 must be different than ssE + if bytes.Equal(ssE[:], ssD1[:]) || bytes.Equal(ssE[:], ssD2[:]) { + // this test requires that decapsulation returns wrong result + t.Errorf("test implementation error") + } +} + +func testKAT(t *testing.T, v sikeVec) { + ssGot := make([]byte, v.kem.SharedSecretSize()) + testDecapsulation := func(pk, sk, ct, ssExpected []byte) { + var pubKey = NewPublicKey(v.id, KeyVariantSike) + var prvKey = NewPrivateKey(v.id, KeyVariantSike) + if pubKey.Import(pk) != nil || prvKey.Import(sk) != nil { + panic("sike test: can't load KAT") + } + + err := v.kem.Decapsulate(ssGot, prvKey, pubKey, ct) + CheckNoErr(t, err, "sike test: can't perform degcapsulation KAT") + if !bytes.Equal(ssGot, ssExpected) { + t.Fatalf("KAT decapsulation failed\n") + } + } + + readAndCheckLine := func(r *bufio.Reader) []byte { + // Read next line from buffer + line, isPrefix, err := r.ReadLine() + if err != nil || isPrefix { + panic("Wrong format of input file") + } + + // Function expects that line is in format "KEY = HEX_VALUE". Get + // value, which should be a hex string + hexst := strings.Split(string(line), "=")[1] + hexst = strings.TrimSpace(hexst) + // Convert value to byte string + ret, err := hex.DecodeString(hexst) + if err != nil { + panic("Wrong format of input file") + } + return ret + } + + testKeygen := func(pk, sk []byte) bool { + // Import provided private key + var prvKey = NewPrivateKey(v.id, KeyVariantSike) + var pubKey = NewPublicKey(v.id, KeyVariantSike) + var pubKeyBytes = make([]byte, pubKey.Size()) + CheckNoErr(t, prvKey.Import(sk), "Can't load KAT") + + // Generate public key + prvKey.GeneratePublicKey(pubKey) + pubKey.Export(pubKeyBytes) + return bytes.Equal(pubKeyBytes, pk) + } + + f, err := os.Open(v.KatFile) + if err != nil { + t.Fatal(err) + } + + r := bufio.NewReader(f) + for { + line, isPrefix, err := r.ReadLine() + if err != nil || isPrefix { + if err == io.EOF { + break + } else { + t.Fatal(err) + } + } + if len(strings.TrimSpace(string(line))) == 0 || line[0] == '#' { + continue + } + + // count + _ = strings.Split(string(line), "=")[1] + // seed + _ = readAndCheckLine(r) + // pk + pk := readAndCheckLine(r) + // sk (secret key in test vector is concatenation of + // MSG + SECRET_BOB_KEY + PUBLIC_BOB_KEY. We use only MSG+SECRET_BOB_KEY + sk := readAndCheckLine(r) + sk = sk[:v.kem.params.MsgLen+int(v.kem.params.B.SecretByteLen)] + // ct + ct := readAndCheckLine(r) + // ss + ss := readAndCheckLine(r) + + testKeygen(pk, sk) + testDecapsulation(pk, sk, ct, ss) + testKEMRoundTrip(t, pk, sk, v) + } +} + +// Interface to "testing" + +/* ------------------------------------------------------------------------- + Wrappers for 'testing' SIDH + -------------------------------------------------------------------------*/ +func testSike(t *testing.T, m *map[uint8]sikeVec, f func(*testing.T, sikeVec)) { + for i := range *m { + v := (*m)[i] + t.Run(v.name, func(t *testing.T) { f(t, v) }) + } +} + +func TestPKERoundTrip(t *testing.T) { testSike(t, &tdataSike, testPKERoundTrip) } +func TestPKEKeyGeneration(t *testing.T) { testSike(t, &tdataSike, testPKEKeyGeneration) } +func TestNegativePKE(t *testing.T) { testSike(t, &tdataSike, testNegativePKE) } +func TestKEMKeyGeneration(t *testing.T) { testSike(t, &tdataSike, testKEMKeyGeneration) } +func TestNegativeKEM(t *testing.T) { testSike(t, &tdataSike, testNegativeKEM) } +func TestKAT(t *testing.T) { testSike(t, &tdataSike, testKAT) } +func TestNegativeKEMSameWrongResult(t *testing.T) { + testSike(t, &tdataSike, testNegativeKEMSameWrongResult) +} + +func TestKEMRoundTrip(t *testing.T) { + for _, val := range tdataSike { + // fmt.Printf("\tTesting: %s\n", val.name) + pk, err := hex.DecodeString(val.PkB) + CheckNoErr(t, err, "public key B not a number") + sk, err := hex.DecodeString(val.PrB) + CheckNoErr(t, err, "private key B not a number") + testKEMRoundTrip(t, pk, sk, val) + } +} + +/* ------------------------------------------------------------------------- + Benchmarking + -------------------------------------------------------------------------*/ + +func benchSike(t *testing.B, m *map[uint8]sikeVec, f func(*testing.B, sikeVec)) { + for i := range *m { + v := (*m)[i] + t.Run(v.name, func(t *testing.B) { f(t, v) }) + } +} + +func benchKeygen(b *testing.B, v sikeVec) { + pub := NewPublicKey(v.id, KeyVariantSike) + prv := NewPrivateKey(v.id, KeyVariantSike) + _ = prv.Generate(rand.Reader) + + b.ResetTimer() + for n := 0; n < b.N; n++ { + prv.GeneratePublicKey(pub) + } +} + +func benchmarkEncaps(b *testing.B, v sikeVec) { + pub := NewPublicKey(v.id, KeyVariantSike) + prv := NewPrivateKey(v.id, KeyVariantSike) + + if prv.Generate(rand.Reader) != nil { + b.FailNow() + } + prv.GeneratePublicKey(pub) + + var ct [common.MaxCiphertextBsz]byte + var ss [common.MaxSharedSecretBsz]byte + + b.ResetTimer() + for n := 0; n < b.N; n++ { + v.kem.Reset() + _ = v.kem.Encapsulate(ct[:], ss[:], pub) + } +} + +func benchmarkDecaps(b *testing.B, v sikeVec) { + var ct [common.MaxCiphertextBsz]byte + var ss [common.MaxSharedSecretBsz]byte + var ssBsz = v.kem.SharedSecretSize() + + pkA := NewPublicKey(v.id, KeyVariantSike) + prvA := NewPrivateKey(v.id, KeyVariantSike) + pkB := NewPublicKey(v.id, KeyVariantSike) + prvB := NewPrivateKey(v.id, KeyVariantSike) + + if prvA.Generate(rand.Reader) != nil || prvB.Generate(rand.Reader) != nil { + b.FailNow() + } + + prvA.GeneratePublicKey(pkA) + prvB.GeneratePublicKey(pkB) + + v.kem.Reset() + err := v.kem.Encapsulate(ct[:], ss[:], pkA) + if err != nil { + b.FailNow() + } + + ctSlc := ct[:v.kem.CiphertextSize()] + + b.ResetTimer() + for n := 0; n < b.N; n++ { + v.kem.Reset() + _ = v.kem.Decapsulate(ss[:ssBsz], prvA, pkB, ctSlc) + } +} + +func BenchmarkKeygen(b *testing.B) { benchSike(b, &tdataSike, benchKeygen) } +func BenchmarkEncaps(b *testing.B) { benchSike(b, &tdataSike, benchmarkEncaps) } +func BenchmarkDecaps(b *testing.B) { benchSike(b, &tdataSike, benchmarkDecaps) } + +func ExampleKEM() { + // Allice's key pair + prvA := NewPrivateKey(Fp503, KeyVariantSike) + pubA := NewPublicKey(Fp503, KeyVariantSike) + // Bob's key pair + prvB := NewPrivateKey(Fp503, KeyVariantSike) + pubB := NewPublicKey(Fp503, KeyVariantSike) + // Generate keypair for Allice + err := prvA.Generate(rand.Reader) + if err != nil { + panic(err) + } + prvA.GeneratePublicKey(pubA) + // Generate keypair for Bob + err = prvB.Generate(rand.Reader) + if err != nil { + panic(err) + } + prvB.GeneratePublicKey(pubB) + // Initialize internal KEM structures + var kem = NewSike503(rand.Reader) + // Create buffers for ciphertext, shared secret received + // from encapsulation and shared secret from decapsulation + ct := make([]byte, kem.CiphertextSize()) + ssE := make([]byte, kem.SharedSecretSize()) + ssD := make([]byte, kem.SharedSecretSize()) + // Allice performs encapsulation with Bob's public key + err = kem.Encapsulate(ct, ssE, pubB) + if err != nil { + panic(err) + } + // Bob performs decapsulation with his key pair + err = kem.Decapsulate(ssD, prvB, pubB, ct) + if err != nil { + panic(err) + } + fmt.Printf("%t\n", bytes.Equal(ssE, ssD)) + + // Bob performs encapsulation with Allices's public key + err = kem.Encapsulate(ct, ssE, pubA) + if err != nil { + panic(err) + } + // Allice performs decapsulation with hers key pair + err = kem.Decapsulate(ssD, prvA, pubA, ct) + if err != nil { + panic(err) + } + fmt.Printf("%t\n", bytes.Equal(ssE, ssD)) + + // Output: + // true + // true +} diff --git a/dh/sidh/testdata/PQCkemKAT_374.rsp b/dh/sidh/testdata/PQCkemKAT_374.rsp new file mode 100644 index 0000000..8498b26 --- /dev/null +++ b/dh/sidh/testdata/PQCkemKAT_374.rsp @@ -0,0 +1,702 @@ +# SIKEp434 + +count = 0 +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +pk = 4484D7AADB44B40CC180DC568B2C142A60E6E2863F5988614A6215254B2F5F6F79B48F329AD1A2DED20B7ABAB10F7DBF59C3E20B59A700093060D2A44ACDC0083A53CF0808E0B3A827C45176BEE0DC6EC7CC16461E38461C12451BB95191407C1E942BB50D4C7B25A49C644B630159E6C403653838E689FBF4A7ADEA693ED0657BA4A724786AF7953F7BA6E15F9BBF9F5007FB711569E72ACAB05D3463A458536CAB647F00C205D27D5311B2A5113D4B26548000DB237515931A040804E769361F94FF0167C78353D2630A1E6F595A1F80E87F6A5BCD679D7A64C5006F6191D4ADEFA1EA67F6388B7017D453F4FE2DFE80CCC709000B52175BFC3ADE52ECCB0CEBE1654F89D39131C357EACB61E5F13C80AB0165B7714D6BE6DF65F8DE73FF47B7F3304639F0903653ECCFA252F6E2104C4ABAD3C33AF24FD0E56F58DB92CC66859766035419AB2DF600 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD91282214654CB55E7C2CACD53919604D5BAC7B23EEF4B315FEEF5E014484D7AADB44B40CC180DC568B2C142A60E6E2863F5988614A6215254B2F5F6F79B48F329AD1A2DED20B7ABAB10F7DBF59C3E20B59A700093060D2A44ACDC0083A53CF0808E0B3A827C45176BEE0DC6EC7CC16461E38461C12451BB95191407C1E942BB50D4C7B25A49C644B630159E6C403653838E689FBF4A7ADEA693ED0657BA4A724786AF7953F7BA6E15F9BBF9F5007FB711569E72ACAB05D3463A458536CAB647F00C205D27D5311B2A5113D4B26548000DB237515931A040804E769361F94FF0167C78353D2630A1E6F595A1F80E87F6A5BCD679D7A64C5006F6191D4ADEFA1EA67F6388B7017D453F4FE2DFE80CCC709000B52175BFC3ADE52ECCB0CEBE1654F89D39131C357EACB61E5F13C80AB0165B7714D6BE6DF65F8DE73FF47B7F3304639F0903653ECCFA252F6E2104C4ABAD3C33AF24FD0E56F58DB92CC66859766035419AB2DF600 +ct = 0FDEB26DBD96E0CD272283CA5BDD1435BC9A7F9AB7FC24F83CA926DEED038AE4E47F39F9886E0BD7EEBEAACD12AB435CC92AA3383B2C01E6B9E02BC3BEF9C6C2719014562A96A0F3E784E3FA44E5C62ED8CEA79E1108B6FECD5BF8836BF2DAE9FEB1863C4C8B3429220E2797F601FB4B8EBAFDD4F17355508D259CA60721D167F6E5480B5133E824F76D3240E97F31325DBB9A53E9A3EEE2E0712734825615A027857E2000D4D00E11988499A738452C93DA895BFA0E10294895CCF25E3C261CBE38F5D7E19ABE4E322094CB8DEC5BF7484902BABDE33CC69595F6013B20AABA9698C1DEA2BC6F65D57519294E6FEEA3B549599D480948374D2D21B643573C276E1A5B0745301F648D7982AB46A3065639960182BF365819EFC0D4E61E87D2820DBC0E849E99E875B21501D1CA7588A1D458CD70C7DF793D4993B9B1679886CAE8013A8DD854F010A100C9933FA642DC0AEA9985786ED36B98D3 +ss = 35F7F8FF388714DEDC41F139078CEDC9 + +count = 1 +seed = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC81ADDE6AEEB4A5A875C3BFCADFA958F +pk = C9F73E4497AAA3FDF9EB688135866A8A83934BA10E273B8CC3808CF0C1F5FAB3E9BB295885881B73DEBC875670C0F51C4BB40DF5FEDE01B8AF32D1BF10508B8C17B2734EB93B2B7F5D84A4A0F2F816E9E2C32AC253C0B6025B124D05A87A9E2A8567930F44BAA14219B941B6B400B4AED1D796DA12A5A9F0B8F3F5EE9DD43F64CB24A3B1719DF278ADF56B5F3395187829DA2319DEABF6BBD6EDA244DE2B62CC5AC250C1009DD1CD4712B0B37406612AD002B5E51A62B51AC9C0374D143ABBBD58275FAFC4A5E959C54838C2D6D9FB43B7B2609061267B6A2E6C6D01D295C4223E0D3D7A4CDCFB28A7818A737935279751A6DD8290FD498D1F6AD5F4FFF6BDFA536713F509DCE8047252F1E7D0DD9FCC414C0070B5DCCE3665A21A032D7FBE749181032183AFAD240B7E671E87FBBEC3A8CA4C11AA7A9A23AC69AE2ACF54B664DECD27753D63508F1B02 +sk = D60B93492A1D8C1C7BA6FC0B733137F3E37BFE55B43B32448F375903D8D226EC94ADBFEA1D2B3536EB987001C9F73E4497AAA3FDF9EB688135866A8A83934BA10E273B8CC3808CF0C1F5FAB3E9BB295885881B73DEBC875670C0F51C4BB40DF5FEDE01B8AF32D1BF10508B8C17B2734EB93B2B7F5D84A4A0F2F816E9E2C32AC253C0B6025B124D05A87A9E2A8567930F44BAA14219B941B6B400B4AED1D796DA12A5A9F0B8F3F5EE9DD43F64CB24A3B1719DF278ADF56B5F3395187829DA2319DEABF6BBD6EDA244DE2B62CC5AC250C1009DD1CD4712B0B37406612AD002B5E51A62B51AC9C0374D143ABBBD58275FAFC4A5E959C54838C2D6D9FB43B7B2609061267B6A2E6C6D01D295C4223E0D3D7A4CDCFB28A7818A737935279751A6DD8290FD498D1F6AD5F4FFF6BDFA536713F509DCE8047252F1E7D0DD9FCC414C0070B5DCCE3665A21A032D7FBE749181032183AFAD240B7E671E87FBBEC3A8CA4C11AA7A9A23AC69AE2ACF54B664DECD27753D63508F1B02 +ct = 5C0BD37BFCBB23AEFD37ADF1F95AE78DCFEC2981E50E81FDD0569E0FF53F117A5B3D2969F3E51A074487B12329665A7B23B16478F012015E271A46992D953E62A51BA0100BF6A50E8EA2A393D5514CA02DEFB5B62860C1A6AD27FBDE9387AB86F5D519021693FA45CF8F55DF2E007583720AE637CB2DE891A2CE272565CE546079EF81AF08277D8511D164447826310DB06C28E58DEF4B4ADD55D45FAB3036C9C7D3975E01590BA490768F84B758B2FD6E64A73704887BF43AB5DFA4ABC79D2B01A843C8B7F3673B458DD9260810BC5D54C30E7E84F63CCABB37BA00587A36563AC5D02C82482AFA6EFE1E29A187D42CDB6039CA35269CD5CEE420820699AE03BFEDB1A84772BCBA36AD2E34AD025B2C6E0302A4753B1F5320C51796A9CE2E4A543044A6C4B47CC94959618052ED806425849983F0890B8A9ED935AC86E8FB2FA819C793CD90FCBE790018D8FE6B6B89FD54DBF3F1BDE4FB3574 +ss = 9D7EDCCC78E60EFDDD75D585AD920730 + +count = 2 +seed = 64335BF29E5DE62842C941766BA129B0643B5E7121CA26CFC190EC7DC3543830557FDD5C03CF123A456D48EFEA43C868 +pk = 1BD0A2E81307B6F96461317DDF535ACC0E59C742627BAE60D27605E10FAF722D22A73E184CB572A12E79DCD58C6B54FB01442114CBE9010B6CAEC25D04C16C5E42540C1524C545B8C67614ED4183C9FA5BD0BE45A7F89FBC770EE8E7E5E391C7EE6F35F74C29E6D9E35B1663DA01E48E9DEB2347512D366FDE505161677055E3EF23054D276E817E2C57025DA1C10D2461F68617F2D11256EEE4E2D7DBDF6C8E34F3A0FD00C625428CB41857002159DAB94267ABE42D630C6AAA91AF837C7A6740754EA6634C45454C51B0BB4D44C3CCCCE4B32C00901CF69C008D013348379B2F9837F428A01B6173584691F2A6F3A3C4CF487D20D261B36C8CDB1BC158E2A5162A9DA4F7A97AA0879B9897E2B6891B672201F9AEFBF799C27B2587120AC586A511360926FB7DA8EBF5CB5272F396AE06608422BE9792E2CE9BEF21BF55B7EFF8DC7EC8C99910D3F800 +sk = 4B622DE1350119C45A9F2E2EF3DC5DF56A27FCDFCDDAF58CD69B903752D68C200934E160B234E49EDE2476011BD0A2E81307B6F96461317DDF535ACC0E59C742627BAE60D27605E10FAF722D22A73E184CB572A12E79DCD58C6B54FB01442114CBE9010B6CAEC25D04C16C5E42540C1524C545B8C67614ED4183C9FA5BD0BE45A7F89FBC770EE8E7E5E391C7EE6F35F74C29E6D9E35B1663DA01E48E9DEB2347512D366FDE505161677055E3EF23054D276E817E2C57025DA1C10D2461F68617F2D11256EEE4E2D7DBDF6C8E34F3A0FD00C625428CB41857002159DAB94267ABE42D630C6AAA91AF837C7A6740754EA6634C45454C51B0BB4D44C3CCCCE4B32C00901CF69C008D013348379B2F9837F428A01B6173584691F2A6F3A3C4CF487D20D261B36C8CDB1BC158E2A5162A9DA4F7A97AA0879B9897E2B6891B672201F9AEFBF799C27B2587120AC586A511360926FB7DA8EBF5CB5272F396AE06608422BE9792E2CE9BEF21BF55B7EFF8DC7EC8C99910D3F800 +ct = E4F8CA44EA281F30009DBF0CF812C6193B2E488E6CBDEBA99E421ABD70BA1FBF809F5D9CED745F9DB9E3666AF910A25B3AB179575D15019AF37568B386928F0448DA4CA43C2A58940AF03AABABB662EDFD1752EE011F175C34B6B3D0E3B5FFF2DA995FFFE021B7371D2145495201C72E8B326C80E1F5DDC3365085D307087A85B17584B61200D2115434320961DE9CC23A4D29008756D2BCA99C80FF3D189FDF0F825A0E001726A3AD60BF8164C737971C9868D22EAB96397F47921564B92527099B8FB5712AE0001CFBE968BB87D2D51279C01989D6747190049D01465C7B80DE91682978478A71DC301714AB1FCD6E4AE297441F680C70345B38894495EF6AA112AE5994B608165B00FD93AB7546999C3800C7A40576134ADAB162777E98699FE9780375104F788E7F4B0D3C9783013131AE87609C4C47979C39D788E79518617D710F37E4ACD635013BA43BA645D229881B7058DDD716760B +ss = 68C17AB42604D799578D835DC7256001 + +count = 3 +seed = 225D5CE2CEAC61930A07503FB59F7C2F936A3E075481DA3CA299A80F8C5DF9223A073E7B90E02EBF98CA2227EBA38C1A +pk = 026656630E8C79F68BE7B3EFA96969922859DDDFEF5DAF19BD4891E7A4806A6D438B346BC832F10754FE0B75CA937E01B3E8B77EEF410145F254E77AB2CFDA7BC7A42507EF8F91024D14113C63B89C8663ADFE755CF3AA0FE90C38C6B765A98980720B1092FDA9EB9677AEA04900B822F112408BF3727B999D44A07A5327623D7FC69A9E52E3A8EC66FE11047CAE20731F2E2522E647B7F5C445630A4A5472AEDCC6212302476F9A539BD6D286E5BDE01B8265FB3D081C2E0B83DAE8378D73651486F96B9F9FDD8BAE795E3FF42BAF19D568B287BA84F59FEB1AA200E9204BFBBDB1E49045A0D62CDCF0808282EE2311F600EE8D82C707DE99EEBCD358FD8A3E77874B46B115BF4E5E323C31087171401E2E0226598EB04C95338094E7C24B6E089B75E425C98BF89651FA6A9348607A8A6DA08C2DEA2E8A88A33D7C41710BADBF607B90A57002EFFD00 +sk = 050D58F9F757EDC1E8180E3808B806F5F114AAA7D2AA844222D0A658998298638BB2C80C40B4B76260672401026656630E8C79F68BE7B3EFA96969922859DDDFEF5DAF19BD4891E7A4806A6D438B346BC832F10754FE0B75CA937E01B3E8B77EEF410145F254E77AB2CFDA7BC7A42507EF8F91024D14113C63B89C8663ADFE755CF3AA0FE90C38C6B765A98980720B1092FDA9EB9677AEA04900B822F112408BF3727B999D44A07A5327623D7FC69A9E52E3A8EC66FE11047CAE20731F2E2522E647B7F5C445630A4A5472AEDCC6212302476F9A539BD6D286E5BDE01B8265FB3D081C2E0B83DAE8378D73651486F96B9F9FDD8BAE795E3FF42BAF19D568B287BA84F59FEB1AA200E9204BFBBDB1E49045A0D62CDCF0808282EE2311F600EE8D82C707DE99EEBCD358FD8A3E77874B46B115BF4E5E323C31087171401E2E0226598EB04C95338094E7C24B6E089B75E425C98BF89651FA6A9348607A8A6DA08C2DEA2E8A88A33D7C41710BADBF607B90A57002EFFD00 +ct = FC9C6A593AECFFAB44DA40D39FCB1125851C1412F6B0038748729A7898EB6E3026A0FA09F7D700277CC9ED0E8592359BB6B41D7166EE01A97B09CC3C9745FEC2227081AA712A2EDC326130097C1A65972EB1A7893D2DFCE9C18DC7AD58BC077D35FE091CA69E8F3B25B2E6AF5700852416FD07B666DCD52871A106D8BBCC1CFF3F6C846F7247BC2A7849C897AD8950630A9EAEB9B873B99AC7F280FB60AE81EC245629AB010777FF7771722CDAA8465F6B51028D3B1015249AD2C3A235975BB03B2783639AD9C46E0994FEDA332C4FDC0C315E86F1EAC7F3903BC300436B6B8430A00C6C284C229AE9504B835374883E8F2028A28F1CC486E9225E1F32BD0F30EE3260C3F68A92CB803AC99C901CE42B63B300E0AEECA9421B87652CC78E612CB62C09F8E8A62B1D55FD175A563C3F232D007633B915DCC8ED5B0C2EA85990457B092738C5AD704560003EE88C3362C9247820853932DB9E61EE +ss = E0BD6870B0308BACBDA1061628CE8F0D + +count = 4 +seed = EDC76E7C1523E3862552133FEA4D2AB05C69FB54A9354F0846456A2A407E071DF4650EC0E0A5666A52CD09462DBC51F9 +pk = 5B9EC441333B3876B02FE62FA4D3E87CF7149D2EDFCFE02B76A81321127907AC1732B2C5FCB0213ADDCB2AAD482BCCBF26CC1B1CF96601B9E9F6AB077759ED1BD8C5F1B579076E75EF089FF1E820502AB9CC67FF4822D310A2BE1D6C9BF7B019F958A360B7B4A73315B8D9D63A0152E58534D86B49875D88E3817C6A603CF2998403D73CE72685044FABB74BF774C4FA31C1E27A6250C7CA6EDF817DF6859D188594304301999FF1575039CA1B8D401C16A9DB57D54CD389703038555F30D2B0687B268DEFBDDBB37DC87E9C4A00409C6CE46075205CB2121B012801A1D46233CEDF1BE83A19D83EE8DA55C9C4279EA1B011B2386CA2390D62B906F9ADF2AD5B0EADF2D90D2705B0AD1FAFB71D0B7F8F41600065C9F4CFBA6A1D7316905BAF5F5DCC127EFAD9F34453548B8A6439B08C58173EDB7067068C0DC33AED4B3D2217E29CA2F5199984833600 +sk = 66B79B844E0C2ADAD694E0478661AC461C84F5D40C73FDE4C2D060E671DCAC99C0F268F85ADDCC7681A032005B9EC441333B3876B02FE62FA4D3E87CF7149D2EDFCFE02B76A81321127907AC1732B2C5FCB0213ADDCB2AAD482BCCBF26CC1B1CF96601B9E9F6AB077759ED1BD8C5F1B579076E75EF089FF1E820502AB9CC67FF4822D310A2BE1D6C9BF7B019F958A360B7B4A73315B8D9D63A0152E58534D86B49875D88E3817C6A603CF2998403D73CE72685044FABB74BF774C4FA31C1E27A6250C7CA6EDF817DF6859D188594304301999FF1575039CA1B8D401C16A9DB57D54CD389703038555F30D2B0687B268DEFBDDBB37DC87E9C4A00409C6CE46075205CB2121B012801A1D46233CEDF1BE83A19D83EE8DA55C9C4279EA1B011B2386CA2390D62B906F9ADF2AD5B0EADF2D90D2705B0AD1FAFB71D0B7F8F41600065C9F4CFBA6A1D7316905BAF5F5DCC127EFAD9F34453548B8A6439B08C58173EDB7067068C0DC33AED4B3D2217E29CA2F5199984833600 +ct = CDD134EDDFA2B2E9C6DE157E1ED68E0FE13798D243A0630D1566A459680A7BF93D81664866F560D59DC18D43D6400734087D4F3831C6003E21D02091176298BA40154011081E972AA1AD5BA3CB8BB069A721E2C09946D1F45AB6B9B3CD7E867F910AA6CD409413BB6488EE88F6013C44D83C55B0748DDFE5312571F7A1745B5AE94EC18002A367ACC7C83D33AE2391641FB0F8D129F8CD249E718EA5828F76EAF5CE053100711E510D753215604C0AAA6B325DD6D81E564983EF3820BB4908F6BBDA16B3B6E1FE2D0D01C3C33A73E2BB6DEF6D83B8D0481E376C8501E0FD3617273D4BB9577D6AB6485530D08116C4D9EE8A76767FEE8BE93B04BD1101AD86B642F8D3D8C3F5349734C683AA20420AD3BF250235962505CC934D87E32020F717D0018457838079ACE67F7E6C5D81DB53C40A54D755911E042778471E610F8D8860E47505F63234161100CE2EE0B19ED2A830497D0D70A6E61BD3 +ss = 18C6E6AE1527E5A612E98F2018FDD744 + +count = 5 +seed = AA93649193C2C5985ACF8F9E6AC50C36AE16A2526D7C684F7A3BB4ABCD7B6FF790E82BADCE89BC7380D66251F97AAAAA +pk = ABD9D07C7D8957F8F043CF2565406A71C0F5845EAA8F0C633EE78D2EEFD276C9D65E8718482EB0CF082F16C8A91F9F779D29E04D402A018EF75E4758206392C6502D4AB3B539CB505E86DDC39F2472CDCD47513116B38AF8B591F70230497CB55F5F9F80C7DFB698B8CF8EA7110292D067C0340E6F815839DEBA5F2AE53840E1114587A3E45F1206E0679F0783B3833293A425FA7D7F5DF6D5077B43081DAB970D49CB0202B89503F46CB3C599D7A258A63A29913D0DF9DD0D5D7A0F50CF837D7BCEF760B56AF9D0A34627754F7B4A7DBBD2BD9D4836F7B848D9EE008E8E9982887E4E7DC36AD259715C3A54540241D995CB115E5DDD727567E36EEB0E858CFF4394EE030159E52C03035E36ED796864E88301AB9B98BEA197396E09569477CC25192EC3235C5A24F3794D2B39295E3F108AE3365470E68FCB81F9E097284BD88F7FEDF6AC91255B1F02 +sk = 7EC408F52C9AA723D0C41D9987682A5F96EF1EB28E65EEF99B8CE6DDE26D979BDAA37158C7649ECDA51A5D01ABD9D07C7D8957F8F043CF2565406A71C0F5845EAA8F0C633EE78D2EEFD276C9D65E8718482EB0CF082F16C8A91F9F779D29E04D402A018EF75E4758206392C6502D4AB3B539CB505E86DDC39F2472CDCD47513116B38AF8B591F70230497CB55F5F9F80C7DFB698B8CF8EA7110292D067C0340E6F815839DEBA5F2AE53840E1114587A3E45F1206E0679F0783B3833293A425FA7D7F5DF6D5077B43081DAB970D49CB0202B89503F46CB3C599D7A258A63A29913D0DF9DD0D5D7A0F50CF837D7BCEF760B56AF9D0A34627754F7B4A7DBBD2BD9D4836F7B848D9EE008E8E9982887E4E7DC36AD259715C3A54540241D995CB115E5DDD727567E36EEB0E858CFF4394EE030159E52C03035E36ED796864E88301AB9B98BEA197396E09569477CC25192EC3235C5A24F3794D2B39295E3F108AE3365470E68FCB81F9E097284BD88F7FEDF6AC91255B1F02 +ct = 73B277597F6861DF9C9929397A7216AAFFFE94C1DC522D31B2FE4ECF64A09A30B754186519B9C3FF348B7249F32B944E04BD4B7AE719027CD8F38559585FE916014EF21607D4D7A83DA63237B7623D68F42F4134CFC701630B74B2C7C36BAC6C9B1F90334783C37219D6D72CF501A468B5B0149CE42C491E71AC55FB68C628CE0347873FA0E9D6240DF43D6C4FD8945C901666A92DDC068ECB3D70D99A2AE2A968DD69C201BE9B2AF07502F88CBAFA9B02E4B9208F3FD9DF66DB977DF0469F547A62522454617BA14357572F17CDD74A1C5756EF0B49797665905B00FE9A2665C8A3AC0FEB3164B9EC129C7C8C0015AD3532A0B332F0ABA0CBCEA670F81664C6543E94BABF1C455316350B07E70AC9439048009E6E25D222884CB7A6989CBB50C226C9951172F2A18D7308660ABC0B441355E4D938441B4C18B18BB20A35B8D9EBA2EE5FEF04300BB300C4B6EFAD7D9B9E29AA430F4ACD9D8645 +ss = 377A154FEDAC0A7DF1DFB1409D34F568 + +count = 6 +seed = 2E014DC7C2696B9F6D4AF555CBA4B931B34863FF60E2341D4FDFE472FEF2FE2C33E0813FC5CAFDE4E30277FE522A9049 +pk = 235B59C4931909215173C321D2BE02DDD8F4227D1AFAF566BBFCDD8E9280F63A7D1AA346C3B01F429AD66689D9912A5C4C36241A314200403282704705DBBBA6917E131FCF5541BDED9478B08649619D8F6FE9D4D5BB9B28F3F851C5AFF4B31A4D94858876BF3218D68FF88A8A018E55B5B9C7A664001BC7793C2052841329A80DAC59A919BB4C51ED106FF12646327E08E6CBA2F3FA92CBA3655640681E93EAF9F8A0BE0092576BD86705BA9FA4546F78659A8F4C162763F37F8376E480BB15F15AF187B02A1ACE9F9A994977A076FD8C9CEE72C2F58B6C06570602F37989AFC2A59068F95F510AC7565D90B8D101CCF66A3C3A758319F690D59843F1E5142A701B2622944DA1D8B48E0AD0FD888EA0D41D018C387AEA8B7A9DCD0F1536822A9E7C9056784637637D9FA3F242C84A20B29558A3C73DC38462527F6659572317DAD665727952769FAB00 +sk = C121915BFEF6ABDFC177DAE2F5A24218C701C945CF4234DAB0E8518592EDD35881C0F413DE3FB6CFB2370801235B59C4931909215173C321D2BE02DDD8F4227D1AFAF566BBFCDD8E9280F63A7D1AA346C3B01F429AD66689D9912A5C4C36241A314200403282704705DBBBA6917E131FCF5541BDED9478B08649619D8F6FE9D4D5BB9B28F3F851C5AFF4B31A4D94858876BF3218D68FF88A8A018E55B5B9C7A664001BC7793C2052841329A80DAC59A919BB4C51ED106FF12646327E08E6CBA2F3FA92CBA3655640681E93EAF9F8A0BE0092576BD86705BA9FA4546F78659A8F4C162763F37F8376E480BB15F15AF187B02A1ACE9F9A994977A076FD8C9CEE72C2F58B6C06570602F37989AFC2A59068F95F510AC7565D90B8D101CCF66A3C3A758319F690D59843F1E5142A701B2622944DA1D8B48E0AD0FD888EA0D41D018C387AEA8B7A9DCD0F1536822A9E7C9056784637637D9FA3F242C84A20B29558A3C73DC38462527F6659572317DAD665727952769FAB00 +ct = A0D5B0A211B37E232BD846CB7EF30CF81548BB89C96DAA08D39762F5FEE12B3960C72C30C53D4B2ECF4A998A569C546125C7EB7790EC006C4D6927CAAF595D87581702B4FB5C395F2DEE22E137DE40CB337907B150D9C1607ECECB6E9C33A614EEC4EE7BA3AFC681935B95BAD200DE71E80A5E19C54780E2DFA06E3EB7ED7941A84FC337B9CF13CFA6A14BC15E0AC72A89022BEBED520F71C01E8A4B63ABB904CAAB210100C8FDA4BBB7BEFD1B574376A7855F75DBD39546DACAC66E668192D4B54975504658AA2E438095BCD41FF86173DC6AE72B72FA8C136B1702623DCF514EADF17033D18018408DB3CD77354B383365DD2327B18047A882EC4966ABD4470FB256993DBA121E5F00FE250E218E5185C10085627D0FA545EDE681390F4B9FCC10748DA761A7353E52C4CC1135F1CD53EB5F6960410F7195A33DC1E2BCE864BE7B200D81FC2F5A7F0027E416D28AF12A64C1DCC5BC596E9636 +ss = 20702B740B8447FEBB904FC9BF411637 + +count = 7 +seed = AEFB28FDD34E0AB403A703B535296E3A545CA479C1D8148E2D501B3C8DD8B1034BD986F13F1A7B4671BE769359FD2AAB +pk = B35A0DB3B8FBA28F72C047A5E4676FBEFF9D14B938D20C6A38DCB38F2CBDF3C5B4B789695DCAE46833A572FBD116A7966FC1407E72B000CBC49BD2ABA200E58A59BA975A956DEFB144A8C37886CE65FB7AEC52A67976BA830C0C51200DE5D03108064D78CE79DFEA0FD539BEEA00D911697F499BD056294C565A483F855CCD2A461927BA6CAEF894A1798AE8EFEF2DEA8078817A5FCEFA4A688F91BE9D714794F96D075600D7B785DC0E72174BA8AECECDDD1FF68EF6859C867BB6FB58FABD9CBC1B52424EB6CBA25185B01907B8DF6CFF1CB7F399A8A73D888A40018279D0888FFB2D0B7EE92E74942B567D6842706E965F7B44319AE8148552EF363285E6F1F6F655BC8693F6567793897E8A7B9358A6AE0075C9413DA7945EA98E2296A7A84562E58BE632381699449C62E3DEE3E3E42B93034C2002A91B7330E5FD22D884185314767B660C499800 +sk = D86634ECF96CC2603761E284C0E36734440251BC6D79105402015AFCF1B6E3F84D723CB0B6DC224BDF7B6701B35A0DB3B8FBA28F72C047A5E4676FBEFF9D14B938D20C6A38DCB38F2CBDF3C5B4B789695DCAE46833A572FBD116A7966FC1407E72B000CBC49BD2ABA200E58A59BA975A956DEFB144A8C37886CE65FB7AEC52A67976BA830C0C51200DE5D03108064D78CE79DFEA0FD539BEEA00D911697F499BD056294C565A483F855CCD2A461927BA6CAEF894A1798AE8EFEF2DEA8078817A5FCEFA4A688F91BE9D714794F96D075600D7B785DC0E72174BA8AECECDDD1FF68EF6859C867BB6FB58FABD9CBC1B52424EB6CBA25185B01907B8DF6CFF1CB7F399A8A73D888A40018279D0888FFB2D0B7EE92E74942B567D6842706E965F7B44319AE8148552EF363285E6F1F6F655BC8693F6567793897E8A7B9358A6AE0075C9413DA7945EA98E2296A7A84562E58BE632381699449C62E3DEE3E3E42B93034C2002A91B7330E5FD22D884185314767B660C499800 +ct = B4C21958149D7CB56C45669273AD8D8D3A4F0CC2334E7EC6D38C5F39A9DB08DBBB2AA246F2A7D0C204FA34FAA30D76EA76A6026B02B50026736C0007B38358AE10570494B3A9D431F3B4658ABB737F2C7D4C11B20DACA1D5D455C3AD05970EEE452DB1A83E92FDA138C9F76076003923082298E36A8425304EA83A0E978581673DC5457833BC488304A1F8F4FF832231FBAA643D53CD0DBBB2E97034CFB172F5A996026100A592AE49711B17FD7C12F8D676A8E821694769193DF59BC266CBBD0DC735DFE39BCF6C75BB129D70AE6FFA6D9CEA4CA13AF6D93AF4F700691CCEAA2F3FBEEF2F962DB0E429015D6CC25C4CE5AD3577FBD68C543594008B37D6D18E4AB4DA3201D10AB437BB3B6353AD219164BF01FAE551C0E65F9976FB5A992EB6ED2E50D44DEE844568D5C9C7785F646C2498AFC12C28EF075B9C2C3B6F6D301CBCA4C251DA4AE0E39C0049D5D61D0F8EE4D1E9699CD16863DD2E +ss = CBC8B73A7F31E6E4B909DF774D17E1A2 + +count = 8 +seed = CBE5161E8DE02DDA7DE204AEB0FBB4CA81344BA8C30FE357A4664E5D2988A03B64184D7DC69F8D367550E5FEA0876D41 +pk = AC97BE89E1D09C95148DCA3A189D52B8C39251DFDD534264C0CAC77ECD7E0A6A4625E95CD0FDAD68522C20AAE8D0FFABC262E95F3A1401A0626EC88F43FD1403B1EA5D052D89D65501E3DFB735BA92EAFA34AE5657322957EDC1DD52FF5620B85412355A1C2C866405269FCEDF0045092A0D136D64834DD7DE0BC7ED46DBC671C5C34AA76147E65670A569B349646412BA9D015155D85BC39075FEAB1DB50042B570DAC10028C016EB01199EB50C03DB532F675E1FBC00FDBF70D756C71DF66BC63831B42AC1F4EBD7B2F5042E00053F14EC10A803B69B5455E80D018263D184B8220300640C0442A82667258387F2A7FDD26425E07E4637F159951E16D460D7C89F131BE2FDBD6C0069C1F781FA789FE5BC00805BC7390C6300C6E075710C0394AC840DBBEC175620ECFB0AAE71902EA5141CFBC0B4473C954C67C62544412DBE142401013D9C984200 +sk = 0610678FF4DC3128E1619F915DC192C244DCAF91D70AAAE9BCBB952354FE199605F4E8F1C3685DA286275601AC97BE89E1D09C95148DCA3A189D52B8C39251DFDD534264C0CAC77ECD7E0A6A4625E95CD0FDAD68522C20AAE8D0FFABC262E95F3A1401A0626EC88F43FD1403B1EA5D052D89D65501E3DFB735BA92EAFA34AE5657322957EDC1DD52FF5620B85412355A1C2C866405269FCEDF0045092A0D136D64834DD7DE0BC7ED46DBC671C5C34AA76147E65670A569B349646412BA9D015155D85BC39075FEAB1DB50042B570DAC10028C016EB01199EB50C03DB532F675E1FBC00FDBF70D756C71DF66BC63831B42AC1F4EBD7B2F5042E00053F14EC10A803B69B5455E80D018263D184B8220300640C0442A82667258387F2A7FDD26425E07E4637F159951E16D460D7C89F131BE2FDBD6C0069C1F781FA789FE5BC00805BC7390C6300C6E075710C0394AC840DBBEC175620ECFB0AAE71902EA5141CFBC0B4473C954C67C62544412DBE142401013D9C984200 +ct = 08A36B7D52A8370AD5AAEC88961ADCE21B28151D3A29C55586730657C3329265EAFD9F5A34E6244FDB1199BD9C8BDE1455EF983E95E501FCBACD909D94005A65696622471267F87844B2E40D3FB17B19CF875876B79986263BB9C1E99D3E82FF3885B8AF9AE9072CE964029FD701C9AA228D4FB525540F03E13BDA0EDABA7B3AB5EAE7044F60D50F61EE3AB1BE1558F45254D7CEE84B6E9529AE78BF24F070873A75B6D901D27E2CF3854BE26A6BA6B37B81B739A6895F18866C3CD5DA15FF135C6DE75A322194452C701BD73083A1EB948095E5AB8B1DF1C769EE0194260DBBE31F8299B790EC41ED291646BBCE2C25D67688ED5BD3C43DC7CD31CBC8657CD61A8D20FC41B4CB1C4B206C20B5C9E54107110187B486D381F1E33D7A5F9D40A222BBD318C5163C4B55E37BB7464F6D1AC678A0450DC4824B3B708C6DE35F1A117D16F4FC939BAF860B01D5F49BF66A77D2A3010DD6082D9B7792 +ss = 1246DD9FC2F3E56DE0C452A7D2B86573 + +count = 9 +seed = B4663A7A9883386A2AE4CBD93787E247BF26087E3826D1B8DBEB679E49C0BB286E114F0E9F42F61F63DEC42B4F974846 +pk = 668881CAE185276DFD6A43218A42DE7723EE833E27D1C7066D86080ED653E65F617A217FD3F42C759B8A8DA42460FFFBF38846FC04FE01A4E96287DB081B3D4E2E59BDB428E60F5ACC955E2EFCCB170E6C12C36F8EE7B9E95E75849D93EEA25695FD495A641730AE6DD041B40200233777DAD6720778A2058FECD4048F1A08DD9796F0B71E269479DDF211882CCF3E50F36C1CAE87412DE375B5AEC42375D05404F4C3780091A98C0281AFEC3118B99BA9FB578F244859243EDBDF507810E6D3D07A0D73BE513B96BD9B0E4101341D69E37F4B2CEC9F64C6465B4C00F87CAB1564A1BD1DBC20B3BC93D77217A1D74FC937C7C9AEE5EC4972C347BE332D2B6E8982F725AD0C56340474601ADDB1AE6619792302AAC9E9FC331A4D0B2BFBFE40905540AF3784B3231E6081E388637E35528963552E1BF79AD06B57B6DAC762D80FF9B0A34BAA7C69287701 +sk = D322D56D8EF067BA1F24C92492B9C56D661BC2DBCB9B8E0FF1621C1B0328A2BE50D39C528D9B2989CA705201668881CAE185276DFD6A43218A42DE7723EE833E27D1C7066D86080ED653E65F617A217FD3F42C759B8A8DA42460FFFBF38846FC04FE01A4E96287DB081B3D4E2E59BDB428E60F5ACC955E2EFCCB170E6C12C36F8EE7B9E95E75849D93EEA25695FD495A641730AE6DD041B40200233777DAD6720778A2058FECD4048F1A08DD9796F0B71E269479DDF211882CCF3E50F36C1CAE87412DE375B5AEC42375D05404F4C3780091A98C0281AFEC3118B99BA9FB578F244859243EDBDF507810E6D3D07A0D73BE513B96BD9B0E4101341D69E37F4B2CEC9F64C6465B4C00F87CAB1564A1BD1DBC20B3BC93D77217A1D74FC937C7C9AEE5EC4972C347BE332D2B6E8982F725AD0C56340474601ADDB1AE6619792302AAC9E9FC331A4D0B2BFBFE40905540AF3784B3231E6081E388637E35528963552E1BF79AD06B57B6DAC762D80FF9B0A34BAA7C69287701 +ct = A8A6B1ABA6920A714B66734100197CDD934E56FE7E98ECB11B6B7A2975A939E5AAADA310E063A0C15A32136F02767A49361635704FF700D019D06583AD98FD283C5138BE0A591430DF5560C9F83C9B256DFF69859FD6D08E2FC811DC59D2D2F081510F9F48640CF261CBCDBA7101D19453344F2CF82E4307E4EC21C09C2A5DCEDF387CAD493A2E1E8D6F657043D207F441605D7EDB21730ADF82B04A364A730A2E728D1B0136EB3F1ED669E17125C6B7E6922B306C3CABC46B20071ADE1021767A8E4977F70868F6FF9F6F9D2AD6A9051374C7F94BBCF1F8B82E3C00F522B515134D8763CD6984BF86F28DF8B766556FDCA9E8697EB4D7F1604DF738AE1307EC008C6A6B2EB5184407F64991A94A49DC0CCE01879EF0A781B7F47A31F3579EF53AAF9B7818E4C818F8F262CB5BAB557D594833F7AA3016EFB757773F8DC9DCA55FFCFFC6D28E3BC1D701A52D911F82CD7F717B3215D5E5FAA555 +ss = B09D92921E68FA2CD595FF094B9BAA6B + +count = 10 +seed = 980D0BA7C8F8B23D0E948A6029FF2659810EA1360064663A8994D0333C8543EE5FF5D6D5C9ACF446E61DC464F792B9D3 +pk = 41DBDA29EE49155B922C93C96B7F12D55194828187F3E11CD38DAD1AAFA7F6A6FA9E1C4C12658F4A7541B2238EE9A5AAB532520CB61E0071B7C7932DE780BFA88D10766CB04C1957C964A850C00D9F3C79DAB54320B5D83C11B831651D7E8981AFA8523C5FA587868EFF138A7D009322269125F89B2F2E1CD4C38F29385000A8EBA4C70D67890ED38317E2FC12BBA2B246CCF9ABED1B05A5D52B1D83BDE8FCC43C5F6BAD013E7C125B72A711CC32B000EE81A50BAB72EFD106E560A93FECEFD96777630F607CF75090C049FD7A9EF88A2BF6F423933909A66916F4003D6A6AB0AE9D192591742E59ED338675F6D21A7B58844CCC054C325E369E3C67B658CC8192EED3BE171888712942826D7A4D8CAB051002C4082A05C7DCC8B4C267A3861AAC5F415DFC6594BDE00BB3164008B7BED93597CF39B7484574704CAD537275B7BEC8C2FEFECFEC18EC00 +sk = 2F1D8A3BEBB34540324B9485FDF3D5BE1913E716E52EF135BBC36077D16C70CF656E07A895F704902629630141DBDA29EE49155B922C93C96B7F12D55194828187F3E11CD38DAD1AAFA7F6A6FA9E1C4C12658F4A7541B2238EE9A5AAB532520CB61E0071B7C7932DE780BFA88D10766CB04C1957C964A850C00D9F3C79DAB54320B5D83C11B831651D7E8981AFA8523C5FA587868EFF138A7D009322269125F89B2F2E1CD4C38F29385000A8EBA4C70D67890ED38317E2FC12BBA2B246CCF9ABED1B05A5D52B1D83BDE8FCC43C5F6BAD013E7C125B72A711CC32B000EE81A50BAB72EFD106E560A93FECEFD96777630F607CF75090C049FD7A9EF88A2BF6F423933909A66916F4003D6A6AB0AE9D192591742E59ED338675F6D21A7B58844CCC054C325E369E3C67B658CC8192EED3BE171888712942826D7A4D8CAB051002C4082A05C7DCC8B4C267A3861AAC5F415DFC6594BDE00BB3164008B7BED93597CF39B7484574704CAD537275B7BEC8C2FEFECFEC18EC00 +ct = DB347701F4B35DA8C147211207E85D9C2C138BD70FB59C57934427752F7E5204E74219DA08D06FCADD41BA4DF8B4BAA43B7B8B060BBC0105157CFCC311115421135229AF37F20F877D8CBD920312224A6D3E14718AF0ED326E944767D2B572A72E4EEBBB24890288765281D638019C75728B3966805A9558316CC41AA941FE60455F07FAB8A3161409CCC84D2D872183797E25888C5ACBBED0F5AF785CCB3967558C98D500690FC821192E058BEB8234CF709E7478911CBBFAF062DCBD11982973CBEED625FA2DFB561EB458109E821FA20DBDBC54FAB936A173FA017BF53B17B51F63DA3BCD5EBC83F60C9B6D546C48262E7E8AFF53388EF6FCB8D4A94CA003F24FFBDFD262CE5C151F9628C3DDED96226F0110FF0D524B43AAF19BB4D659D8F2C4CFC5220426D0DE7C365D6141445F9F9CEC0EBA4ADCF726A213138543FE79A72046380DDB831AF0004EE70EE09B57FC1632907938568F14AC +ss = B49ABAAE30A790FECE54A3F113FD575B + +count = 11 +seed = 6C029462CA42ED520F10A579F52687101105E0B90C6E7BFA582A4C112B579D5AD0A0ABD38F72ABCFDCAAF5893A112BDC +pk = 3727C2F466E3E3209BB9A28D2E721BC651AD9D0F06F50347FF911F19D2E9DF1AFB7AADCC589B7E40C25F0108066F5D0DC02E243A74140188A075505372E2981C2BDC310625E5CABEA344C18D8B14D0F3793A47C45739F89139C1E19DB5DC708E607DA782EF5EFF5E07960109DB019C2B786D515A479BC30B4727D458A50680668CBA757C6AD86408931424697B71B5A2593547CB56B21A0C420708640556F80A47A9D4A000593601D8010205A02E167BF296D5AD0625B294964076A507594779DEDCB4D1E423F83FCA1C63B473D3A69AC77E7A6729DBD925436E0300BBD20C06ADE192EDAFAE35E724EA8ECE69CBD16072D756323C15D3270FA9D83F62EEE2C06BFF4D77C70025AF9D5BAB73DF9F6D375F5F01322771D24F67BA11FB7A89538BD274AFFF7C50BC5A471C806F7712DCF529B90238667F4F1050AC8212E428F36BD0FE6422BED3AFC5AC01 +sk = 31BEDA3462627F601CBC56F3DDF4424E204C429A2AF01AA8E9151242EFBB30DBD557B64979456ED0E3E8AF013727C2F466E3E3209BB9A28D2E721BC651AD9D0F06F50347FF911F19D2E9DF1AFB7AADCC589B7E40C25F0108066F5D0DC02E243A74140188A075505372E2981C2BDC310625E5CABEA344C18D8B14D0F3793A47C45739F89139C1E19DB5DC708E607DA782EF5EFF5E07960109DB019C2B786D515A479BC30B4727D458A50680668CBA757C6AD86408931424697B71B5A2593547CB56B21A0C420708640556F80A47A9D4A000593601D8010205A02E167BF296D5AD0625B294964076A507594779DEDCB4D1E423F83FCA1C63B473D3A69AC77E7A6729DBD925436E0300BBD20C06ADE192EDAFAE35E724EA8ECE69CBD16072D756323C15D3270FA9D83F62EEE2C06BFF4D77C70025AF9D5BAB73DF9F6D375F5F01322771D24F67BA11FB7A89538BD274AFFF7C50BC5A471C806F7712DCF529B90238667F4F1050AC8212E428F36BD0FE6422BED3AFC5AC01 +ct = 1727DC42DF2D04F0AE833C20A9FD83E230A810C1660204260F8CC4C1129F57B5FF160AF7DEA5A060F495B21D83347118E581647B4334019BEC70D8EA75F2D19228505F32831B505DA9139FAE8A9265CD475198352B2E10B0E4C4B44FE1227768302B16DF5CFB4C9CFC5B5F1EDB005475046B86CBB7D572283B0E85D7C1F33C6D57D8CE05D8A4DBCA3372C497C1936D35E0013D4BB585F080C88D9CE375BDB6BC31501A31011E5CB262E82DE1D0574623E14DC733B5D7A8644DBC0175AFAFDE58E5CCAD7989D9ADB4EAC5029FA946BD509B63BE8E6E41F41C1898AD01C94103D6A3E17B96B7C19F8F6978B8C6F8BF12187E61FF80B25632ED37AE2B8EDE698A394CA3480179E35B3A4E47CEA3F26BB74642DC00069A058757D75F26C82DA3881FEB28A875CD4B1CD775B7982F9FC2702C0AE7A859CCB880092356824563ABB5E79648118FD6C81D591D0239EFD9E6DAFDDCFD07372FCB258DACFA +ss = A663DA396F96655AED1602ACFB1C83B3 + +count = 12 +seed = DB00120937570D62331F4C3F19A10465231EFF46465CDEE336A0D46AA1E7493DF80F18617F9FFD0476CF7784A403EF4F +pk = 4CA4DAF17B19813A22D6CA2AE239BA3E2C5593249E1D798D0FDF57E74596A18760EF706784C677FB7390223AFB26A183B12FFA51BBC701C88BA3AAA3D871CCDD7C2936553469527228DCB18D1DDE2E3339DE94DCAF7901C4311C67BF2FF055CBBB7F13720F2B5026158F266ECD01C27130547A89C9ABDF2193A554934E121B8EAE74C862D9236C1D94B4318F643B200EEA147952384421BA7EAF6BCA50B48866D025A9E101C287A3CC1EBDE69B35A6BDFC823D904C8B6885B412E7416FCE1AE03F931D221AB9BE8F73F66A69929D35FDB291CD25D351647CC59B3202F4255C29F382E3E041407FCB2968AAA1BDE8FA7CCA4C1C84E76BC79D9D2C81C520670FD5E27EAFCDB8CF900947AAC8BD975030EAB9B301BA1B2D3199699A476CD1C3BCA367175C06AC5DBDAA69EF0122B620CA218FECE279D8D9921709E869BA5867098A2ABACE72D905F9B30900 +sk = CBDFF028766D558AF4466EF14043A1A964288E066695F6610A3FF37C401463403E91F53E7B89CED7721756014CA4DAF17B19813A22D6CA2AE239BA3E2C5593249E1D798D0FDF57E74596A18760EF706784C677FB7390223AFB26A183B12FFA51BBC701C88BA3AAA3D871CCDD7C2936553469527228DCB18D1DDE2E3339DE94DCAF7901C4311C67BF2FF055CBBB7F13720F2B5026158F266ECD01C27130547A89C9ABDF2193A554934E121B8EAE74C862D9236C1D94B4318F643B200EEA147952384421BA7EAF6BCA50B48866D025A9E101C287A3CC1EBDE69B35A6BDFC823D904C8B6885B412E7416FCE1AE03F931D221AB9BE8F73F66A69929D35FDB291CD25D351647CC59B3202F4255C29F382E3E041407FCB2968AAA1BDE8FA7CCA4C1C84E76BC79D9D2C81C520670FD5E27EAFCDB8CF900947AAC8BD975030EAB9B301BA1B2D3199699A476CD1C3BCA367175C06AC5DBDAA69EF0122B620CA218FECE279D8D9921709E869BA5867098A2ABACE72D905F9B30900 +ct = 78D61E2AE434AB6A7F0DE50A61C5E0872F73C33FBF79B1F47FCAF705467BAF5C82A0BAABFABB0AAFE8B6A8547FD2290955B0C7224164016C1A2CFD68974B6BDB93B57CA0E7F3268E75A5C21AE514FC411D2C1257830723B00025B49E2AFEAF7CC5F0E8CD05DA54FE104C1EA79F015B5B25CB39C3309A3AF4540AF404293B62E371627AF7EF702D64267F003116B3056418A8480ED137DEFEBE385628CEE94EB0A260ED9601F6399DA434DF6C29994705B0EA5A8E0836E776B70A8F638D690E58FDEDF8AFDDA6FA6A13DF274FCC37ACFB313F59CF928AA7911D1A400058581BB7EDDAF5313826B1A30F3E18E4568A2B96EF83E951DD17921BCB419C22ED246E8B5A90319CBF5474C064D611C34DB82B3234F001FBCD73882D42D12F310B1748C51350F31594AC61D95A880597BBECCE8B5FA0EB17D83F714CC0338C615639A3FCD718736E7085E83CE4016B9DD7B06AC35D1A127A4ACF6973862A +ss = 040192B84326A814B18C80CA838F94C9 + +count = 13 +seed = BD26C0B9A33E3B9B4C5D7EA32D5BD1FC371015BE163C86F584E49BFD5362C8D8341161CD1308115B2A03B7E5EADDD418 +pk = D5DB4E282AE88F7CF3D2714C2603A73464BA1480BB8380EEAA4438FB56497079A962AF996DDD5CEDD9AB826042E3494BD4E43697073900816D69587993486898A4C70E490ECF1241C39220C736EE270A041FBCAE61786174E677B5853B86409381D9A44535C7CADB1FD7BCE8EE00B0114826C33A4A86B4060F19A27B42EE76C884EF687CE597FCF2BCDB51F621D50CFB0823A17660D0CDAC36851ED0D59AFFEF4CECE68B011AE1BBA7C2C42FF094A4FA0451973AD866477B95C9361CF5DDFC1D94493A55C1B2BBB011485D4F4F6EEEC0A3530AD4FD3CDB6BB0C8840178BEC8738B648C7BD79A49A2D5205F2EB0FCA34883E99835A631A83E779298D66A4D507F7D5B2606688A453BC0FF6A30A5EE91B417A401A4DA09E689AA5BA84C04EFE246906E915832F873B83786DE28FE72D0DAEA035747E8FA556E622BA9E693487500E6A44BD5B6E1AB1C7600 +sk = 4C04310BEA66305C6CA8BA6B8F61CA96E9EDAC80932AA0C57BAA480CD8A5BC44B98B1F0AE30325D09046F901D5DB4E282AE88F7CF3D2714C2603A73464BA1480BB8380EEAA4438FB56497079A962AF996DDD5CEDD9AB826042E3494BD4E43697073900816D69587993486898A4C70E490ECF1241C39220C736EE270A041FBCAE61786174E677B5853B86409381D9A44535C7CADB1FD7BCE8EE00B0114826C33A4A86B4060F19A27B42EE76C884EF687CE597FCF2BCDB51F621D50CFB0823A17660D0CDAC36851ED0D59AFFEF4CECE68B011AE1BBA7C2C42FF094A4FA0451973AD866477B95C9361CF5DDFC1D94493A55C1B2BBB011485D4F4F6EEEC0A3530AD4FD3CDB6BB0C8840178BEC8738B648C7BD79A49A2D5205F2EB0FCA34883E99835A631A83E779298D66A4D507F7D5B2606688A453BC0FF6A30A5EE91B417A401A4DA09E689AA5BA84C04EFE246906E915832F873B83786DE28FE72D0DAEA035747E8FA556E622BA9E693487500E6A44BD5B6E1AB1C7600 +ct = 28F71DB04148FC2AC4EAE01B7F0AD6C382428CD3EC9875948A0B1B9FE4DF00A8138439F779BE259DF85AA61419435B7E2318E99A982E0117FBCB8FBA8C0CEAB5C6FAAD44482FFEC27A688BD49E28463ECCB25D08BCF7604ED2FBBAB6640A4B87A650B41621B72509FE0CDFF8E60071E70A61583C0BCA1BD0F4FEB57BB57DE922D36E4A9D52C08FFDDB4F54859BD796FD7183A2ECB695B68A17C3C68901D121613BE0297400732EA38C548CE390F4F8F0688709C7079C7EC42FE632E954057024C6C459AB474B6CD16D49D00C41CBBA257D0E3027A02BC29373746E01D0326253B0EFE5F839B6DCD0085E638A9AEBDB07FAEA9FA9CF54CECE8CB65069F4D7A9A82BAB6AA537DB3BBE4E84EF182DADAE6A03E20146ED55CAD3CBADC5C5AA963BB41CFD8EC787BABD1CDB329FCC2CCACAE2DEADB7DDEDA266322F8F338BE09A46E468A6F2CBDDD4D0773E00C665870DBBB3E529CDABC10176C0E9D4 +ss = 897ECF117CAD056AA7607F485F5EDBBD + +count = 14 +seed = E2819EF86853BCA1B9DEE7EE1C1619988964F9A913E635AACF0D96CA6E0300D084329DABD8F149E24176D22757404260 +pk = E30D37CC8CB6C2D560EDBF4A063539BFDFAA52D97802652A299A955D18FF253CE8528339E1539D60216D16AF30DA5C7C220FB587536100B638DA38F505FC6D8724259501E7FC037F781BBA379CD3839867D290FF2679C925726DF80F09C1C11E16DAB4CDDB647C716623B96A99018289196013C72B51D9C056F07C58F62B4D7E1B45ECD4AC34A8F5E0F3A7A64F3ED0F3423A04D4C630CDCD832BDA5CE714A36EC5007DAE0097883B09743D3D0D2BB23CDD2632AA0350D58E16B2C04E914B5E4904E4BC79F30412784EE926A8450436B0843C64FBC4B29E996CCE1501A0B006A2CF72B4B501E86FEAB5DA59E67A9D7B56D053E79E2293E3F84D5CACA9F101FC146A74E029B136C56FFB3C734D5CD6F99A6AA600FE427A45F7FF75811766B9AD018921DE96E8AF0227405A7A752448095BE78FA16DA7B9A8439A4ABD0D29DC47B128A8777921DC2E73E101 +sk = 38A0D5F41D7DC1896EFD1B45B04856342DFA1132C7F742C89D311C9D211ECC47B0FBD1966E7DDB27197F6401E30D37CC8CB6C2D560EDBF4A063539BFDFAA52D97802652A299A955D18FF253CE8528339E1539D60216D16AF30DA5C7C220FB587536100B638DA38F505FC6D8724259501E7FC037F781BBA379CD3839867D290FF2679C925726DF80F09C1C11E16DAB4CDDB647C716623B96A99018289196013C72B51D9C056F07C58F62B4D7E1B45ECD4AC34A8F5E0F3A7A64F3ED0F3423A04D4C630CDCD832BDA5CE714A36EC5007DAE0097883B09743D3D0D2BB23CDD2632AA0350D58E16B2C04E914B5E4904E4BC79F30412784EE926A8450436B0843C64FBC4B29E996CCE1501A0B006A2CF72B4B501E86FEAB5DA59E67A9D7B56D053E79E2293E3F84D5CACA9F101FC146A74E029B136C56FFB3C734D5CD6F99A6AA600FE427A45F7FF75811766B9AD018921DE96E8AF0227405A7A752448095BE78FA16DA7B9A8439A4ABD0D29DC47B128A8777921DC2E73E101 +ct = BDC7C8F76ABA0194AF62D89B9C5D5B0BFC4D761DF50F37B6FEA6B2152D3502D481252D8BCA9607013BA0D8BBE14C773E29E8C6B26FBB01BDA396F0C79EF0223F485A0D772271421BB304C8BFBC17CE0229193FD572DD55F22232075FF92CF9CA401968A740FF9223438AB46453011B913E46BA24837B084BF78F50C08F5688E339155FDDEFC02EA73FCA112CF337994E99FEB4197FE1DD3C916190D70712E5A3E044FC93012D6DFFFA2AE0C9E7468FC0BF18F7215586B893B1A82522CCB49C8BBA4958D086AE447E3F728CB5D226C0E3D8441B5AE8DC35471E7762005E02E90F5967B733BBF91892C6161DF290FCEFB99D62EFE5699BCB5B46461A582B95930526661A4DED3DDDF7652FA26153F14441B8E701F61F20D3AB5FDC3FDA0BDE5404C526D1AA0D809231C0DCBC0A96E9535A6D9C7ED2FED9E92B84EB16802BE9C9D32EDF69A9A6BDA30E2B00F2B73B108499499829C416F24AE55877 +ss = 694A4A8AAD90783D407AC750E7B787A1 + +count = 15 +seed = 669C4EF8A051CE201DA65FC4BC34D398EC1F806276FC5D987AD71D93BC12DC8F107B58BE6E8422A0795C88CB9A0E7488 +pk = FE2CDF7A0ED6A9DACE00C76608D0BD33C07C8BBAC34F9558F69AECCAE7343179A4EA723676C7BA725080FF81B01C9B96628E9DBFC8A000B48679C63F10AB47077ED339F8304AEDDF12E5A0B07C5F618B82F55A38BF9F7A8BC609B93F585AE9A84C0BB7666320BA0CED79A14FAC00B75391565182BB83C1437C2013965EAAF5D308B3BC4B89F2008BDE4305580370A4DBC40BDBC18E77D7F646CC519F503D5627673AD6BE01F5480D2A33AB8BC0A595DE3213D679C2477399F42826CCE2E9769F66EC9B54D4C43C82229DFB98D55EF5D4CC5291CE9F5E957035AE8E000402F80121D9E7FA3F013247950C54BA77B5F60D68C1D81FFAD450F93179B10A73F84B96A12273338619984B6D14BD3F5EDE3543D4F8017854FBA247E8BF44AF7115D269E90B6573694E7EC8BDFC5130205E1E0C2838D52A0CE794025B68674382025F92B7EE382E4E706FE1B800 +sk = 97B5665676E59E3538EBADAA8CD50DF142AE6DC4AE262206EBABA48C74A234C1138525803526A8C29DC7FD00FE2CDF7A0ED6A9DACE00C76608D0BD33C07C8BBAC34F9558F69AECCAE7343179A4EA723676C7BA725080FF81B01C9B96628E9DBFC8A000B48679C63F10AB47077ED339F8304AEDDF12E5A0B07C5F618B82F55A38BF9F7A8BC609B93F585AE9A84C0BB7666320BA0CED79A14FAC00B75391565182BB83C1437C2013965EAAF5D308B3BC4B89F2008BDE4305580370A4DBC40BDBC18E77D7F646CC519F503D5627673AD6BE01F5480D2A33AB8BC0A595DE3213D679C2477399F42826CCE2E9769F66EC9B54D4C43C82229DFB98D55EF5D4CC5291CE9F5E957035AE8E000402F80121D9E7FA3F013247950C54BA77B5F60D68C1D81FFAD450F93179B10A73F84B96A12273338619984B6D14BD3F5EDE3543D4F8017854FBA247E8BF44AF7115D269E90B6573694E7EC8BDFC5130205E1E0C2838D52A0CE794025B68674382025F92B7EE382E4E706FE1B800 +ct = BA99787C22449C2F8C9BEA41CE3D6AF52BDC6AC86EAADBCD63FE9CC2DB9289E56FE6785B1F1223F66E2623F5E0C81C1DCEE787DF1AFF010EEF7E9C9D131629A4153B3061B5BA517A66872AE21EE6CA7C1882161375A3EDFFE6CF04FFD6392932CE627C0739EEA06D7A4A3DAE2A021FA0DA97E15E0DE5933A7C71FB5A9F1DC7882A8AD316AD002261FACE947CA78903C3A013268413015D19F643BBB4183C01041323698600EC8D35DCBB2B757EF32E91A1E8BBE12D9019FBC9AD21E4295131670630E461A07BCBE9097793C7C6EC55688A0B6E4D5C1ED9E8448CB00146F70CA8BD35ABF9DA05ADB017ACBE2FB602F379B8FD1147CB11647ABEF755153060B7BC476B756251C1839CD0F3E1833EB377294B7500A86BF5A6FFA4F8753A09E4E280DFB823127C38C82A39F8CF499847D3F81E1E9574C9119C60D37C8B83AFA661DA9904F31E3667B031B50120B4C3560F5312DB42EE0A1C83C396E2 +ss = C13E65613329AF85AF74CEF46B8384CA + +count = 16 +seed = 9DEBCCFE818F6B5204DB4EA09C03EC9A19DCF1629C1527685B8A29776BB1DAAEC45F8ABF8F0ADC9A8C8BD6E2DF6D8048 +pk = 79D967425432D24A0C3977DAD8B1B74440AAB34950413665F6F0B5CB40C96B78550C950A5F7CD2AAD088AEEBA931F97D0277B11964E501A6A741C08C6445D013B8AAD9CB2DF9B88F9A08E481513016CD46DD0EE1EB56732369A8C8CBA34A2F38947E2290FE61593BBFB1D28DE300CD6F0A175773FA411BA7E6A4ECC136561F1F98DB691603FC53E71DDB911673AE43AE5C6ECED2D899CA95EEA8C26163C5671EAD30F6D800F03DFB43C7A46C7CE485993A489E785A396AC1719C30F751AA9E9A6BC7A0E28FFB7B60A4F4EFC95FD3D8B3694155CDE492DDD10D5A1902C1D096FFD81C8D771E3F00026A9EC646CCDC973A0D4F92C31A1A7EE05A8CC41ACA004BE01DF8A312804F1F905B6F7F099C99885A8213023B2863489779C86C1DF6D9AEA76A1586A4EFDE52A965516D457EF6A9537B7FFAE6B5D31EE6F1580C0DFFEAA7C9C00E3FE7D48720CEBE00 +sk = EF99224A03A85A46EF115474EC5B5D628BD0CF95F3E495FD375B444F9B9C1FC8A23857EEF27896A08FE7B80079D967425432D24A0C3977DAD8B1B74440AAB34950413665F6F0B5CB40C96B78550C950A5F7CD2AAD088AEEBA931F97D0277B11964E501A6A741C08C6445D013B8AAD9CB2DF9B88F9A08E481513016CD46DD0EE1EB56732369A8C8CBA34A2F38947E2290FE61593BBFB1D28DE300CD6F0A175773FA411BA7E6A4ECC136561F1F98DB691603FC53E71DDB911673AE43AE5C6ECED2D899CA95EEA8C26163C5671EAD30F6D800F03DFB43C7A46C7CE485993A489E785A396AC1719C30F751AA9E9A6BC7A0E28FFB7B60A4F4EFC95FD3D8B3694155CDE492DDD10D5A1902C1D096FFD81C8D771E3F00026A9EC646CCDC973A0D4F92C31A1A7EE05A8CC41ACA004BE01DF8A312804F1F905B6F7F099C99885A8213023B2863489779C86C1DF6D9AEA76A1586A4EFDE52A965516D457EF6A9537B7FFAE6B5D31EE6F1580C0DFFEAA7C9C00E3FE7D48720CEBE00 +ct = 509F931C69B91B463F9184495F8036417E4A7D7E59085CE1C500F438B088FF86806487AEED6C644FC04D6C470796F39C18CB689BCC1F01DD65379668EFB5749EA8002F5411B131A6A8F733E7DAD73C553EB8A62428F854D8244BC5137B921ED3F5C5D3E85E981FCA403DA91106023C47ABFF15A8B8B12BCAFFB33E0657C4118C4F9B0B632C77D96807AE509281207E157577E51426897B1D3DA003A30AC4813D725CD8B50141968CCB11877104AB6BC2F30BAC781C228C0378BDF38C79ED5772E505F3B9EAB2F5F075FDACB1C0FBF54B2003EC1EA0436D18F2209100391321A03A5EA2100AAAB510267C97A4C51E99BA40F457B831B8DECD43C51357BB711392B9C60A78B65EC4EF46A9C7A20050D690961502F2E58D319EEF77CA1AAD1E6BEEB36EC89619B38DB2862AFDA4E4F48C359CBDF49BFF88C359BC53EE9416F2B368E410270CA28F498F7D0055AA195855AA118D011490262C8875D8 +ss = 71CF8ED3966D7D1DC1E355644F91FAC3 + +count = 17 +seed = 8098AE7A92C10F707D405F7DEA02C2EFBEF44EFA132BA8AEFE81BD45E543ECEC74F10920AE48A40B0653D63532517F2A +pk = 79E0A7998D558892479C2B99DB360986D18A7BC05EE4CAB08C8EACA5FB1055F535DA75145F817CC1657E756E107AE19D43E5D1C80E7E01AC367F1CF7BBDB785FEEF6AB0AF79504C9561FCFD0EDE7AECE5C70DE22F0D81E7CCF61E248D2F0AC8C556BFEFE25DDD11C06BE87068C01035499FA9D6B54E50D3670C0A6B018F5A93331223B6CCA306B8CF5D3C7F3098A5D320C7C345A329B0A457177C4C3C5B2E18251EE885D017C123958F3AE6E47E38AE36E339038DCCD619D611BC1C303BB0DB7575A0A1E8D64E8115EDE663A90A995896D48CBF2150F30D1037BF501119D23ADCA8E66C78AEDA4E418D1CD4E898F95583C892784E563BE2AB786DD19C41BA07A915685E5DA73830860851F796B89CF02C85F0178D832055F8E098A2C942DB4146B2EE69FA5DAEDC462AA81695F9C1DF98BA2CD9F0875BEB1F8E5D34573610E796A3DA5B112C943888401 +sk = B12F6FD965EA9C5B947DB80FC60C83D5CE44DDDF0CED4891F7CDB79060DABDD40C6B00BCEADB3EE4D5D7E40079E0A7998D558892479C2B99DB360986D18A7BC05EE4CAB08C8EACA5FB1055F535DA75145F817CC1657E756E107AE19D43E5D1C80E7E01AC367F1CF7BBDB785FEEF6AB0AF79504C9561FCFD0EDE7AECE5C70DE22F0D81E7CCF61E248D2F0AC8C556BFEFE25DDD11C06BE87068C01035499FA9D6B54E50D3670C0A6B018F5A93331223B6CCA306B8CF5D3C7F3098A5D320C7C345A329B0A457177C4C3C5B2E18251EE885D017C123958F3AE6E47E38AE36E339038DCCD619D611BC1C303BB0DB7575A0A1E8D64E8115EDE663A90A995896D48CBF2150F30D1037BF501119D23ADCA8E66C78AEDA4E418D1CD4E898F95583C892784E563BE2AB786DD19C41BA07A915685E5DA73830860851F796B89CF02C85F0178D832055F8E098A2C942DB4146B2EE69FA5DAEDC462AA81695F9C1DF98BA2CD9F0875BEB1F8E5D34573610E796A3DA5B112C943888401 +ct = 0B2DF56B13EA8EC412B34EB6B795907BE8CF9285D0F54F4BBAD2F616AD052BDC343BC037B7CE43338824A080B168D55F19F01675994401288643228347B9CBBA4F081773FDC6AA62787A9E9E289A0029D53F64019BA58546C006428E2FBE75172D3357F36D0CE9D667B72571200223CFD443E4A1896C1585A3A2B8AB8BC74220CB17A6A7ACD6A37F3580671FD2DF73028AB52E26E74D53F9BF3D709F3904706B667E9A3F017274A3AB8BAACA666693C072E6489568B3BC1C17652D7307FF3011712C385E36F3AF2DABE643B2FC3C350E4C02C8E828E7B9A297F2B300440EEC731D384FD2DF79B611FBD9758E118B64AE153B67530A188DD19A642AF131E90CA6DC213292B050432544D5ED45C587437F5B1C0253E620F09F8692D5D134D318B71A5AB394CF61D3373D052F6658F55E0E355AAE8ED0DB3F5483FA7FDE38F44D102D71178CFC8CE626D8002E49A160432A1CFA03473235E209A8D6 +ss = FACCC640638E1613E321D6A9BF931BE9 + +count = 18 +seed = D5F23808871544E9C1D6EACE2028362B48E225312F77663E9F78CAFEB512B908CD9E25875D61A16EC615F4B8FF826856 +pk = 9E48237FEDDBA4C4E8E9D431FA629F90A93B80DA0311A7DC67FD8E99EAF2C786DF31118C1A3107A6C1A473A295F84AA95AD4A9B6621901CB875A9627E676338F4BFD14F052D7FD7C256177F7A31DF73C156580B124709BAB66B4A05D892F24D7B9D5412A65B3A21A0165D8D0F30036AFAC724353B41204A7710D07582EB3F575937BBB6CB410AFA5A44DD9756E35B89A9776E0D55E37D25E6C91AFCE336D38FF840ADE3A01FE155957CBC62FCEC03481C775BE0F27A563D5C9FA589159519085080752E8818DE911590E4D97CAECAFAF87C0001E5455474EA8D3050052DBB3BA1F72E1B1A7BD411B629D7D22315EF5C4CC1279B7FF3C84629CF8374E59294722BCC5E2AC38C9E7357A910D84ACB7F395D9D101B2F291ADBAA4AB888AFB02FE84747BA6DB45D23FACC2D4A0E00DB47D2ED9E698733DE9D3EB70781655E186CCA62E213B7F334023715B01 +sk = 9F52AF92CA165FDC38788F2B59BA02E0D21361DEA07AA8A47E2CD4A35DACA8B09C7145DFB568DCA2D01D98009E48237FEDDBA4C4E8E9D431FA629F90A93B80DA0311A7DC67FD8E99EAF2C786DF31118C1A3107A6C1A473A295F84AA95AD4A9B6621901CB875A9627E676338F4BFD14F052D7FD7C256177F7A31DF73C156580B124709BAB66B4A05D892F24D7B9D5412A65B3A21A0165D8D0F30036AFAC724353B41204A7710D07582EB3F575937BBB6CB410AFA5A44DD9756E35B89A9776E0D55E37D25E6C91AFCE336D38FF840ADE3A01FE155957CBC62FCEC03481C775BE0F27A563D5C9FA589159519085080752E8818DE911590E4D97CAECAFAF87C0001E5455474EA8D3050052DBB3BA1F72E1B1A7BD411B629D7D22315EF5C4CC1279B7FF3C84629CF8374E59294722BCC5E2AC38C9E7357A910D84ACB7F395D9D101B2F291ADBAA4AB888AFB02FE84747BA6DB45D23FACC2D4A0E00DB47D2ED9E698733DE9D3EB70781655E186CCA62E213B7F334023715B01 +ct = A57904C3BFE47E496333B5EC33D60788AE7948A6C055E9D7D59DF4AB7C02AE7E785A2F38FE70E6D0F9086AB5E020D399348F27C0891A02501558C9E97B46A444A6AFBF811DD7D11CF79AF001542A92FA0E59D6C5F927FA2D2CC9727B0118927D500B0DFD05BAF7FE5629314F2502F22ED8ECDBECB954444984EC84E509893C70C65E4D497139986F55701BC62CC33C97283EE5BD5C2832571731BDEC0A563966854382A90114C5F9CD142F8369F4176E08F563321F662F4D3AFD861239436AA25F10EBFDFD4D3F8C4A832E3510A3704C1DB4C206262EBF8B41182901E7A4DEBC54FFA218D0AAE0CDDA2C2E5909ED71E62E0FAFC99BF53AF55E4BEB2998D0C2221907F14D35751C0B474786456CB14DA7E79A01A6678BA6AA60FCF8666822F6FCF71E1367DBDB2E6E6315FE4ED24A2351A3DB86278147520DB6F96CEE79FD812EE76CB1CDAC8F3424E201792808BF5A73344CAECF081E2AD720F9 +ss = 019ACAE70F324EF52D715966BDE79FBA + +count = 19 +seed = 822CB47BE2266E182F34546924D753A5E3369011047E6950B00BC392F8FEC19EA87C26D8021D377DF86DC76C24C5F827 +pk = E78527604A03B2262803424C585D407333700CC6415EA598DE84B3A00B553B2CC4EE433D96D5DA3A007C6A18F715F4D90C8CD4DC43F200772D2606F083D85638C12B26512093D1A3724E9EB4374730BAB9F7D7A30ADAB87786979D720C1E337893BDD053AEAA6AE384A972585D00062E8D8F4853FA84E5C1715559A090F1EED6C1E5B7F812B4D3CE8D433E518A66396AC07223932ACB9772FDCA3A70C552AA96AA3EA90F02A2BC8C3C2378D927CFB0E431EF704CA1BBDA0B047D85116FDF6A8DCA906689339DC809C2C00AB2D3C9F88FC9196D21D1CCDD947CFB0A009D14320960AAD5D5B5742CC5FEFE262D8C5C150C7230203D6A1872F84497F20B20F57196F715B528773200A1A48AC8157810A2BED91000DDB9C3E5AA0CAD8CD3EC75F0F1852AF7645CBD60498191E35EEB189CC31C075A472A60E8AA4E9B809CDFC4B2E2D8E9595ED790FAEBA500 +sk = 851EA90FD3854CBF28FE39FB81F68E4B4C094361B4B3511F46403B2955F371F12DEB940ABC80C905BBEF0800E78527604A03B2262803424C585D407333700CC6415EA598DE84B3A00B553B2CC4EE433D96D5DA3A007C6A18F715F4D90C8CD4DC43F200772D2606F083D85638C12B26512093D1A3724E9EB4374730BAB9F7D7A30ADAB87786979D720C1E337893BDD053AEAA6AE384A972585D00062E8D8F4853FA84E5C1715559A090F1EED6C1E5B7F812B4D3CE8D433E518A66396AC07223932ACB9772FDCA3A70C552AA96AA3EA90F02A2BC8C3C2378D927CFB0E431EF704CA1BBDA0B047D85116FDF6A8DCA906689339DC809C2C00AB2D3C9F88FC9196D21D1CCDD947CFB0A009D14320960AAD5D5B5742CC5FEFE262D8C5C150C7230203D6A1872F84497F20B20F57196F715B528773200A1A48AC8157810A2BED91000DDB9C3E5AA0CAD8CD3EC75F0F1852AF7645CBD60498191E35EEB189CC31C075A472A60E8AA4E9B809CDFC4B2E2D8E9595ED790FAEBA500 +ct = A6D8DC0B0DCFFEF0E34728FE4DE79A1D59FC9C9AA0FB6361EE18451550D69B313758E1DA7BE3C9E6783C16DEB7B00603109ACF879C56012635C2925DB4DF0D2FEAA89134C1FD33A487C852105DEFA6DF4BAD559B645C96049811445AD49F1ACCA668CFC12D0561747C4A251CC501A6751C36ADDC183AE86DBE1794DCD7AEB9CBEA6ADF4F18011AC2624D0B0E4AE3377AD2E4E7458693FB3D04C4020F3A008988F5DC8F0801232AD1725DB94C378425EBE6CCB3C6AEEBB9A774663AA8A72988A2C6380F56F2FCCDCE3497903B9E9AA3EB6C0809F21ECD5442E8AECB01FCD8CF9AAA3BE92A2FB0D5D43E5703F8939BF15AA6935997B9DE26A4D83FC4A9CA42D4E89591C698640FE3C5E5DFB925076A393B74CE014E8D257FA543FB29F915C5274F74EA862F6065E93FEE25845322ED62ADBB5A0709C7072F520C9B220FE8EFC67B3F5A9AC21CA2B12EE7001A8BCD24CD1F7776630D9F3025034D2D +ss = 031C5FBEE7FD72BEA84A703A739FF9B8 + +count = 20 +seed = 81401DB81138D6874E91B7C11D59596E4ACE543F5A3471B6FB00999221765FEC3CA057ABE20F03B2D59003375FD71FE8 +pk = E5ADFE2A2841DDE0CBAB4F9A9E8D4EC1A07FA5456ECC04C76AC192B968BC030073D066B1D9129D6B6A74092500E3E812B18E7A77959701696C5C603FADD6E1415AF1F64FDFA173C967195A6A018F3946C3A446AE08013EB73ED4F83BFA103F1E7CE0DFC46D566021C306D197740041802A3CA75CDD8984AD4534D7988A338A31639AD33090488EB76B3120346CF64350EE772C8031A74C7B1362F96A6E969D11B61EDEFF014647540DAF3C9A78BC2975CCE93A2A02B9EF54B3F767D21A5FE9C2D885716079A207BED74B55C34D1D2E4FB8243FCD839916CF1B3F16009A2118E0F012AC828117209E74CCAD66C80D9D7B4BA06330DF23A9122D82A5043C31AF133A6D3A99169C17FC8AF5A42765FA3D96F26B011B9DD08673C53691B011DA58AE666570F8849EBB66855BFAC516720944B65A4B71D6D4F35EB4CBF85E61C02FA9347EA39D8042ED292302 +sk = D304C9389CC973477F169788ABCB9D517E067CF2D7B0AF8B6621970053836C9B24568F4A35E007C88CAADE00E5ADFE2A2841DDE0CBAB4F9A9E8D4EC1A07FA5456ECC04C76AC192B968BC030073D066B1D9129D6B6A74092500E3E812B18E7A77959701696C5C603FADD6E1415AF1F64FDFA173C967195A6A018F3946C3A446AE08013EB73ED4F83BFA103F1E7CE0DFC46D566021C306D197740041802A3CA75CDD8984AD4534D7988A338A31639AD33090488EB76B3120346CF64350EE772C8031A74C7B1362F96A6E969D11B61EDEFF014647540DAF3C9A78BC2975CCE93A2A02B9EF54B3F767D21A5FE9C2D885716079A207BED74B55C34D1D2E4FB8243FCD839916CF1B3F16009A2118E0F012AC828117209E74CCAD66C80D9D7B4BA06330DF23A9122D82A5043C31AF133A6D3A99169C17FC8AF5A42765FA3D96F26B011B9DD08673C53691B011DA58AE666570F8849EBB66855BFAC516720944B65A4B71D6D4F35EB4CBF85E61C02FA9347EA39D8042ED292302 +ct = B44C6CB690A599DA437ED550DE19E05B6DD374BABF7F189C46F209CB261D4B97ED66370B1473DF217BB466B671C6E428E996E7491BEC00E407B27259B3DAA431DEEAE11D337F8B2D9758675B37D1A550DCECB489A5627FD4AB9853B1329ED6A79083E5351CEA79E2544BD4BBD201B81F8F66078690C7C64162F7B4ED2E92A5F806D5B6DABFA4B29D80E6B885695377E6CFEE0A8BD462AF401F62CBF52FCFD2FF7B911D2D02ED29685034344E5531EE7610AD97197CC38C9C935A2096400E196D13D883A7F0583029056F7323AA4D89DD8E775F189B253FC8C7EE4D017E1138DD5317812A4744BD3DE8DA014D29FAFFB81D3CC751701A65BC1539F92FB92281760B69EC962AAE6FC762D579F0166CFFBA0D96019D1C5AC299FC2FAD6E55FFCF84B6A9363A0129766D94B218B7C556B938B6CBF510B0A40D026D99A2FC45E6F48BCFFE7D8AED10C24EBD016261622D7CD57BAE2A0BB48E706D5124 +ss = FBE3D8D78996D62A3652F8B86D15ED92 + +count = 21 +seed = 30B5DE5B73681EC08AAA03F6F2D2169525D25F4042A5E3695A20A52CA54927B85F8BB948FC21DF7DEFC3910B28674994 +pk = B398CB02EC7FD85A5FB95BC0028DEB12D5E18FCCDA3E9CCBC453D9C41EA0D84A790A4657E83B7D50B9A06F607E195C6DC04AF7EBBD0901210A54AA537A9D0A03A41C05D53D67680623279A4304F59472F8E8463C7F20B40F77F212E894F8173F79B04165F343B6E73E871D767F01407A3B7EA88CCF701524226E425B2E2CF6D3636D5EFBBDE4FB117A5ECD64825D80D9FE4E0A3EBB0BC948DE9CB2053ACD9F6879C2FBD300DDC67DD715402DF6EBFFC4D55E7ED1DFA935817C2EFE2DE6991F579CF6033538AD4D2ECE4260DF01BC398F269E7FB1BE66FB0A23F89C013C53496938380DFB64BE070A27AF25822A9B1283703C1BAE428B7BAB4403665946E689E2A21D4C38E6A7A5C8E1135D181570FFB3BCA80167267DD1B09A00F3A201FDE34A24CC30B46314CA4D9E793CBC872798CE511A1F0AC40C580B19E1A8FF78628E400878870C0DFF0E84C701 +sk = 89A6E3BE304A3518FB82B18CA730F0B3B1B7DE5CF0A30D1030216C0057C368AE8D6FE4565D9D5E0540B62A00B398CB02EC7FD85A5FB95BC0028DEB12D5E18FCCDA3E9CCBC453D9C41EA0D84A790A4657E83B7D50B9A06F607E195C6DC04AF7EBBD0901210A54AA537A9D0A03A41C05D53D67680623279A4304F59472F8E8463C7F20B40F77F212E894F8173F79B04165F343B6E73E871D767F01407A3B7EA88CCF701524226E425B2E2CF6D3636D5EFBBDE4FB117A5ECD64825D80D9FE4E0A3EBB0BC948DE9CB2053ACD9F6879C2FBD300DDC67DD715402DF6EBFFC4D55E7ED1DFA935817C2EFE2DE6991F579CF6033538AD4D2ECE4260DF01BC398F269E7FB1BE66FB0A23F89C013C53496938380DFB64BE070A27AF25822A9B1283703C1BAE428B7BAB4403665946E689E2A21D4C38E6A7A5C8E1135D181570FFB3BCA80167267DD1B09A00F3A201FDE34A24CC30B46314CA4D9E793CBC872798CE511A1F0AC40C580B19E1A8FF78628E400878870C0DFF0E84C701 +ct = 5A4033674303F5116A5EB8B8FA8D9C745A8459F1997B5F3D21761E68552270C3C53AD68C76C0AD179C9781633326017B8122E4F5707601C178C777A5A4587D572C6EF1702228D26B428EA4B29876F03120C14B3DBCE50FF01AD329E0836826D54BA969AB6AA3DA251D6133CE270299DFD7BE932A17DFA7C288AC70C780B4DF72396A0069633B83BA9B77CDB79E00FE448133B3EC289E36E80DE32477B4C64304F45B007D0116A979E983E3E177C26190B30B68A7C246BD2CBF56C572EAB6C1FE3E6B7E0AAB44F725DF6417B8257F505C52C93FD195459792E93918020CB1A3FB02844A08C99CDAD3CAF60B92C3E60925BCFB6C6EAB9B9AE302A8AA31A496BCC3750CBD1E2F45EDF63B52711649597B2A80D700E529B8CDC733018D0A1A885B663DDBB6B4D895A063BAC07E2F136C06E10793F0FD474DB4DC6EEB466E22B73F4A16CF73F80B73654DF0005F9998BEA5F0910321449F5967CE8986 +ss = 3D7E8D87B57B2B32DA794159078EA043 + +count = 22 +seed = E335DF8FC0D890588C3E305AC92C7160FF199E07C85760A828933750E3FED8C83B0DBE802234481ECF890A32D7A2884F +pk = 617B81E845C0D725940B3F7B1B973AD95B34B22C6AE8248D2FAE9D53C27516B90D7D64D04046BF49EBE7E3B867E4846A1C0FBA53610901890F5D4E38B9F66AD0FFB340131B393EE8F1DF5071A65EF174A4D119C44ACC8A810AF76CD857ACE288B82BA81CB111BAED16226020710123BFD9AF426AC20CD6E91261D8D963E3D3B6B79895013868E3632F27135B73E4FBECD8CABD31617C4B226F57D9A1BC01E4F935DC1A9701FB3F3433CA3E7A2EACAD2C2177D731964646BA47A3C2CC8F81271AB7459F2041D0B0A1FE6390E4D8849C1078A61174CD9872ABDD96E301E1EA3CE9351D90CAB51E23045E00DBA8249F8BC12192E05080202F34901ABDD0A4A86914CA52B2AFB901A3DEC6E070FD1D953543CBC8016D57F3408A1EDDAEE272E7624F9FA5E27E3E103156C046E8B2BA0B4BEDD4F9528DA6F17AF23E4149D08A1B313CA674C74E168C133E3100 +sk = D569B935CE015C85F792F8F7FB0D83C401514B7E7AC373B9210B7DF08A8B12A9C0385B16BC8D71C7B6945400617B81E845C0D725940B3F7B1B973AD95B34B22C6AE8248D2FAE9D53C27516B90D7D64D04046BF49EBE7E3B867E4846A1C0FBA53610901890F5D4E38B9F66AD0FFB340131B393EE8F1DF5071A65EF174A4D119C44ACC8A810AF76CD857ACE288B82BA81CB111BAED16226020710123BFD9AF426AC20CD6E91261D8D963E3D3B6B79895013868E3632F27135B73E4FBECD8CABD31617C4B226F57D9A1BC01E4F935DC1A9701FB3F3433CA3E7A2EACAD2C2177D731964646BA47A3C2CC8F81271AB7459F2041D0B0A1FE6390E4D8849C1078A61174CD9872ABDD96E301E1EA3CE9351D90CAB51E23045E00DBA8249F8BC12192E05080202F34901ABDD0A4A86914CA52B2AFB901A3DEC6E070FD1D953543CBC8016D57F3408A1EDDAEE272E7624F9FA5E27E3E103156C046E8B2BA0B4BEDD4F9528DA6F17AF23E4149D08A1B313CA674C74E168C133E3100 +ct = 37A3D8C7E16E0E18593EA9C1B6E0BC040F69ABFC622886EF650C4EB5FD1B47CF77D4721C5E1DB49127F54E9917BC5D40549E9297061B007EA80B5E4EB433AF558613C891651564B834D959B4206DA1819D448FFC27A2DD80ACD65011D7AF672885C37C6384572AA16DF8EB9D1A00C477F77578EDF36A4AF373EF6CCC9D05655EC45982C7B69BF88174808F4FE5A9FF7E892E0D0BCAFAECC2C4187A08637659126B8BA4510116B4E7F62B7DB87AD687BCB6346CDA4BFF940DE098CD150BAB054E6F9C03B49F21779BCF1D2414C0EAA56D2301130E269E326E802F3C0014DFB5FAE901B4BE916824266D76B80B2D918CFBBADA3D634718BEA7666D94F28BE9212E076AB7C217832FA343C78CF237DC05AEDC0402519EBE46EB6B362A64B691D05CA9C72C80CB8F2479E927145595DDB3D9A6897C9B328D75CC010BB5AF13357AE0577293EB4099D3103302E74BAA27FF6684BA9243B66D2533FB35 +ss = C24173C7DA58B449DD977568836FF856 + +count = 23 +seed = FBEA1BC2C379F4F8FDCB0DE260D31CDB064C9EA9B1D6DFBE91B3692ADD1D34DEC9C9FFAE7BF5E72ED2743BA3F9F2E43D +pk = 4771098E0B07E996EAFC696CF6C8E10C4ADE3FE1B4764793CBEE4235F873321E9F8F71B2357EA46E481138B3433790FAD710CBD1BE89018F7FFFA5FA3B63BC98E3A6BC83376E4F86FCB866A7756D74D8BA45C86B88925B35352AD0345AD95EB4AC5CF53C6998133C57A569CC1602B9B0897EC8DA43E75291BFF1990DC01CE1B5D727B1447CB5DB432FF62BFCCE6995E04FD81032D276D856F36936D7E05A5CAA76CD90CD013DDA3C80E5FC28C72406C1905925FFFCDC8ADFA41CB12FFE5D2FCBE9DA6A2B567EDB9896B6A03382EFE79FFECB40280A12C78437808100882D45E5C2C2E1EBAE25061E04F14C540849F65CF39E701C46A32988EC7517176BEC1E616A42ED258315A8991B0E1D4158F08571EC0402358A61FF669CDF1E5FCBD08D75C988A6875F7B197A45AEEEC2AC2B43024C304B8B357D002EB51F856AEAA4BDD062A09B8957927FBADD00 +sk = 5CBB141C2763425C274F7404FE530D91164BDF5F413B63F4EDDCC47594FFB9E2C7287FD5714CAF679CD3EF014771098E0B07E996EAFC696CF6C8E10C4ADE3FE1B4764793CBEE4235F873321E9F8F71B2357EA46E481138B3433790FAD710CBD1BE89018F7FFFA5FA3B63BC98E3A6BC83376E4F86FCB866A7756D74D8BA45C86B88925B35352AD0345AD95EB4AC5CF53C6998133C57A569CC1602B9B0897EC8DA43E75291BFF1990DC01CE1B5D727B1447CB5DB432FF62BFCCE6995E04FD81032D276D856F36936D7E05A5CAA76CD90CD013DDA3C80E5FC28C72406C1905925FFFCDC8ADFA41CB12FFE5D2FCBE9DA6A2B567EDB9896B6A03382EFE79FFECB40280A12C78437808100882D45E5C2C2E1EBAE25061E04F14C540849F65CF39E701C46A32988EC7517176BEC1E616A42ED258315A8991B0E1D4158F08571EC0402358A61FF669CDF1E5FCBD08D75C988A6875F7B197A45AEEEC2AC2B43024C304B8B357D002EB51F856AEAA4BDD062A09B8957927FBADD00 +ct = 545FC97ED910F330B4BA794B368DA77BBD174EF9A654487FDCEA4406A438B04FFAA75336C67F4EFB6EA650645CE1B69D1C8E44FE798500BE8B169B7063B1ACC4A9E4AEBFA175783796190C638F47669B1EA271DF591F4730EA87BCE2BA2427BCC3A1F73FC94A6387CB4C3ED80401BFCBCDDECA82DDB51F4622B33104E5D4483E8D99317A7AC5CE38FFAFFA64C7BCF551D5E4DFF9723E998C5B8A6C5B73680610725EB29901E15EBC7B9979720ACF893E7A72945D4B7B9F8304E3F3D8DF2A7A80AA6FE71C341968166CFD9A218B78640E8CF268901506D8F391F4B801C6DE231CA5A43E1CE9F06CA5AA5AD7330A0906CB96DD0D914B33F75C98FFAAD43CE6850291ADE9241DFE69FF699FF7171D38E4FEDFEA0114316D23BAB6F9F214E3D49A1580085340ED30FF160EFF8ED54CFA3067DA31DC71D25C2D176B5157ACD7ECD42B55B8D839218B935EFC0141E6103357A6CD3F3DE4EC8BD20DB364 +ss = A5D8459E0B0C063FF5696743360F4186 + +count = 24 +seed = 7E87FB886BC3C7C9FC12569F465D2ECD12532E76CC27C65644C8D3DD603B0CB2D036C5974E675058F271D5C82AD7A813 +pk = B0CA13F0AE46FFCD00D5DBE90E094F0DA3775987817A4B27A69FBF427827D617B66F48D9C0B6BEA4792F58E08B61A8CB0AA7325487E0000695D8CDF7EFB2B112ADD1A534D6440F298BC6678F67F79D7D2723AEF9D0880EC9C9CF87E90DF158E489DBA4574CFE6037BF2D59046F00FB00FA9105D62AFA83C6CBDBEAE4E5A0E0AD92900FD7B089067E5AB16D61D924127E2C0B4958F39270233921DA842E1454CAA7F95BBD018CBD6B086CC69B50CA35E96F26D8C778CF1459C2B6CE37B321C862DD45077956F4CBCABBE4CDBB5B3F5920EDCCCE03A4C86FD61C9BBF019D74FB3E090A4A9B9D6BD3830EC627D6985529D059077D926480D7D28F76B49EFA9D92032C53C46539AF29F8A2E8015FC1F00081BF59009DAEF6E0E74BB0A3D4DA9056C89C5426A09427732D0A560AAD27DC4B1340CEF6D71A9F7987CC5F3C635EDC523931108D8992083D9DE700 +sk = 293ABB6D1C207927945417CF84883EF06C2D005E0DF6FA70D10F5B8E13FDB305CF307DDC3FEDF97D29089D01B0CA13F0AE46FFCD00D5DBE90E094F0DA3775987817A4B27A69FBF427827D617B66F48D9C0B6BEA4792F58E08B61A8CB0AA7325487E0000695D8CDF7EFB2B112ADD1A534D6440F298BC6678F67F79D7D2723AEF9D0880EC9C9CF87E90DF158E489DBA4574CFE6037BF2D59046F00FB00FA9105D62AFA83C6CBDBEAE4E5A0E0AD92900FD7B089067E5AB16D61D924127E2C0B4958F39270233921DA842E1454CAA7F95BBD018CBD6B086CC69B50CA35E96F26D8C778CF1459C2B6CE37B321C862DD45077956F4CBCABBE4CDBB5B3F5920EDCCCE03A4C86FD61C9BBF019D74FB3E090A4A9B9D6BD3830EC627D6985529D059077D926480D7D28F76B49EFA9D92032C53C46539AF29F8A2E8015FC1F00081BF59009DAEF6E0E74BB0A3D4DA9056C89C5426A09427732D0A560AAD27DC4B1340CEF6D71A9F7987CC5F3C635EDC523931108D8992083D9DE700 +ct = CF160BDE31A7608A72A6DAFED55D5462B177730AAD95324D89B9BE0AC3D51011EA868E907B91841FE54CF57F37B3BD24E5E7470667BC010B6D9D301FB4E91CD5DE594BF0EDB72C29F3EE6577D308D5F27A80F94D3C01483AC70D65A7B4D4259316E85852D339380BDD261A24B7013B82A14CC28C211ED7D20CC3E0CD88160465B2CC50C8A1322D5790F5A52EE78B481D9E30DE657B603FE94AFB409B2D6240C050FCA59D006CCC82BED7FEDD739A7F2565A3D82FE61421FE762625BF6B4E7A8EDE6F378C77AA828F42DAAB6D76F0BEB4D5C89511ACEDEAC1A43839003CA58A145AAE91504A68A851617F12896F1885E8EEEEA7F7C6589BA64BF4418F7388AD43357D867AB4ABA174EBABE44B83DDF32BBBE5018F2E780384CB78781BE0BB92F68CCA4260BB07B23D8E117BE89B150DD67DC64AE41A549A659DC9CB1D06D223904BF88478798333C370009EF7A472506D33A8EF92ADA940C1422D +ss = D5D19932C9F4580ECB0EAAE0504526AC + +count = 25 +seed = AD1424E804F306C7FF513DA4C1E8D445AFCA7BC942FAC5C0B335733AAF70693712ECBDE26EA726EE0F9FD9D52A83B1A4 +pk = 1573C9DABCEFAFC5CAB63298B29009AE04F01B94B4BB5E82D87BA0985736D529B34E33689CB06CD7BD7CD765402F267E6CEE6196C36B004DDB9041A740C6F5DF87AA7B4193C0BA066A11F2FFDB3E76AA9FE79B972D09F0680806181A704D605E159E02891EE12AE4873DE686A3004E51C1B44F529A3B62F5FCEA4C38E874CC82861E36E05A462A9033FF5DAAF515FC8DF26DFE5B63EFE92FC67C58F4B3E2EB5AA28F0D5C00DF09CF57E106A79DC7704185556E2E131A4FCC83DC325838E6D536EA9BF99C46A5E2DE4CB05178E5D6A442B44F8F2E14DABEAF510EF7009F870D730D868F3D25952ECAC032CBB4B7EE645B6793CA1B1ABEF4ABF1F9FD1D266352A8CC1D981CB58BBF2BDB6DF7EC5C2DC5FD57E300C4799375413FD553B1EE65C0FBF245919F5269445C0BEE0313FD8507571782A4D4B01382E93EFF30152D8575ED0F3A856537A4FBFE4800 +sk = 74D87C7556F2671F2D666854A4D6E0738F75A8885AB2972C5C91AB2CA4CB7EB6E9A79AE0C496E90EA77802001573C9DABCEFAFC5CAB63298B29009AE04F01B94B4BB5E82D87BA0985736D529B34E33689CB06CD7BD7CD765402F267E6CEE6196C36B004DDB9041A740C6F5DF87AA7B4193C0BA066A11F2FFDB3E76AA9FE79B972D09F0680806181A704D605E159E02891EE12AE4873DE686A3004E51C1B44F529A3B62F5FCEA4C38E874CC82861E36E05A462A9033FF5DAAF515FC8DF26DFE5B63EFE92FC67C58F4B3E2EB5AA28F0D5C00DF09CF57E106A79DC7704185556E2E131A4FCC83DC325838E6D536EA9BF99C46A5E2DE4CB05178E5D6A442B44F8F2E14DABEAF510EF7009F870D730D868F3D25952ECAC032CBB4B7EE645B6793CA1B1ABEF4ABF1F9FD1D266352A8CC1D981CB58BBF2BDB6DF7EC5C2DC5FD57E300C4799375413FD553B1EE65C0FBF245919F5269445C0BEE0313FD8507571782A4D4B01382E93EFF30152D8575ED0F3A856537A4FBFE4800 +ct = 094C0BE692710E360DCCF7D770D751AD7839B6DFB43C171ED3BA2C8007CFC51F6ACF60E4569FE08006E15804A0E887F1470835B9D80300377F958E2FCE71C2B68C4FAE158BE4099272C1AEFF56C2A3336FB3C55788045585A9016D4D97EB3A4BBA76D9A505942CD9B89557B3A0008164D4A2B03A9D1123E9E54FE47D20306C0F0C445D84ED84FA3B62F2B8110510013FB0B87C0DF58C57CCF7926F4F52C33B7CE199F08E0033A7E55EAF99351C1206D8CDE852A084EC73BC6A0F99FA1B934C4C7D6859D6B46295CFA529005DA3174831D6582C2A34642387E8CA30019805265BF953F1C18DDA05BD8C8797178480CFB2E762C35F924BF658040B9FB2E2C0C91AB9FBD24D98FE43DB45564750825668BFD02800B87AB5AF5DADCCC623FAB1CF4B5118EF883B33E5A60D4D95962497601D9C3C712F77F35AF4492B37FF6A79CF8EEDA3610730BCA7E7F9016FA6CC846E59E73483DA2578A5957BB7 +ss = F777EF5840DD876797535F8122B2DFBA + +count = 26 +seed = 7C33CA0E987226C8524DD56C811FA4D1CCF9995B1E4E4DD5B1481974E88CFABFBF6787775C2611CEFB27ED4403EA9B46 +pk = 64B9965D19319330455412B2460C01E2C88331A400CCFE842A500F198136C01F134E4D7D460E1E99B0760FB26DB04AD2A944021BE16D0139C26CBAD19C89DD3D2E87B49CF614E90A0518F4256C1B3EF10289E1EBF2C8E5934B775FD899AACD0FB872E80FB91DF5C613C9124B3A00242DA316865459961D20A9821943A3CD7A1B52E8C27DA63E6145FEFCE014E4DB82B6ABF548B02DC50004F3CCC088EC06D9D0BEEF82BF005A549D89B2D24F29B593CA7C47A046E76FDB290C0D30B3382D8C3ACFBB55F1DDFCB943E7F919E7D90D0E97905FDD38C826BD45FEB210008C84F82A241BB03737758563ADC718F63D32E6B7B5E999CFF0AE3A70E9BD1EE824B3F06F45D05D572AF49A402C21938008A4D07B3568002AB0A90867422011974D891D20ABCE11B28601A0AF5E3ECD2F8495150133E5C3D2AFD2AC5796EEE9AFC0AC00E901D9E64F411AAB211102 +sk = 013BAB0212D04ECD54B478DAF7274800FBE097D801C58088B66DFF45AD9AA22010B170A6BDAD118817C65F0064B9965D19319330455412B2460C01E2C88331A400CCFE842A500F198136C01F134E4D7D460E1E99B0760FB26DB04AD2A944021BE16D0139C26CBAD19C89DD3D2E87B49CF614E90A0518F4256C1B3EF10289E1EBF2C8E5934B775FD899AACD0FB872E80FB91DF5C613C9124B3A00242DA316865459961D20A9821943A3CD7A1B52E8C27DA63E6145FEFCE014E4DB82B6ABF548B02DC50004F3CCC088EC06D9D0BEEF82BF005A549D89B2D24F29B593CA7C47A046E76FDB290C0D30B3382D8C3ACFBB55F1DDFCB943E7F919E7D90D0E97905FDD38C826BD45FEB210008C84F82A241BB03737758563ADC718F63D32E6B7B5E999CFF0AE3A70E9BD1EE824B3F06F45D05D572AF49A402C21938008A4D07B3568002AB0A90867422011974D891D20ABCE11B28601A0AF5E3ECD2F8495150133E5C3D2AFD2AC5796EEE9AFC0AC00E901D9E64F411AAB211102 +ct = 2261F4BE74D14EF8627FCFE874B02B3FF62B2F30DCA91660A73D2FF24765464AE253CA62957865F8C957867D7858E8D1D29110F33B15025DE695985B081E582C954F8B6F1EEA51430386D99F57037FBB497586F777EDAD7E756574C317F299558137C7B3682466E1ADD74E651A0284A229DEBBEEC8579AEDAE20DAA62D6CE02B0A1F4913AD02C05DE48FAF028DE1607756F4B6A22A4C2BF329DD391546528688725465450131B3D31775594496E32FA32611CE9184DC37D5D7C75DDBCEB653163DB4382DA9CB61FAC7147D7EF27C228A17B02C3B13D037D2437A25014EB25477847E6CE71808490B2413EA4526634E7CC30B650656593A7A6F5977D98373BDD403003BC661559A875F1A784B7448F1BEC02402384F0311C9EC507BA3A073777FFB52527127779545E8C2695E79595DBFF5E48C17431B25B793E062337542D2C371812C007754C9E45A00A18DCA0585EBC078942359E88411CC13 +ss = B2F713B6EE25BD7E567BEBCC5997F6A4 + +count = 27 +seed = 54770EA1252EA2857D6635151194F5F520ADEA8A41E409FF498D40C271359858FE2B084D5B96BEE087B8E8F4DD4E00C5 +pk = 579CAF24BCA30BA44F3214AC535775263C4530AEB8B471F7B92BCF218FCEE3C88F32B03C8202B4B16E88D0F3333A5C2B775FDC04ED6E001A164D01F369A1A8FE5874A86A02D4DEAD4D36B5F5EB86EDCC04606CB20966AF09D52687FFA85B0B45D0A4F2B5F0149805929B56DEC301CD45C9443F116E0A827E22F6676CD3DAE9B099BBE661D2118DD08234C5F936F2102EBBBB0743DACFAFBAE266A440D05715A750314AA1004FDEE91BB4A2B6D8B80E794E56C79A3BC328DA4D7FBDE3F9CD68E53DE212661D1F45D4559EE29ADC7950CE354FD6888EA56CFC7358E80131F9C32241DF762B6BE1349A342DD8E4483FF9CDBF557B5E8C65DB210BC35D33379DE7379F12423427262E261CC1138039779255345E003D8EAF0D3B3887AC221D1DE20A7E11D18EB50D9E5160CC6EDC1C2B0EBEC2AB22626C18396335C9F34BF68A3866ECC081C29A2D410D8D01 +sk = CCB073C4B90BE0AD746E26FB093B60C7E0B4194DB681E84934D511565454BE2532A70B22663D775EFCB50700579CAF24BCA30BA44F3214AC535775263C4530AEB8B471F7B92BCF218FCEE3C88F32B03C8202B4B16E88D0F3333A5C2B775FDC04ED6E001A164D01F369A1A8FE5874A86A02D4DEAD4D36B5F5EB86EDCC04606CB20966AF09D52687FFA85B0B45D0A4F2B5F0149805929B56DEC301CD45C9443F116E0A827E22F6676CD3DAE9B099BBE661D2118DD08234C5F936F2102EBBBB0743DACFAFBAE266A440D05715A750314AA1004FDEE91BB4A2B6D8B80E794E56C79A3BC328DA4D7FBDE3F9CD68E53DE212661D1F45D4559EE29ADC7950CE354FD6888EA56CFC7358E80131F9C32241DF762B6BE1349A342DD8E4483FF9CDBF557B5E8C65DB210BC35D33379DE7379F12423427262E261CC1138039779255345E003D8EAF0D3B3887AC221D1DE20A7E11D18EB50D9E5160CC6EDC1C2B0EBEC2AB22626C18396335C9F34BF68A3866ECC081C29A2D410D8D01 +ct = 400EB3A03C28F5D9DE6513FF995AC280EFFEA99A4811CA7CA97CD5A0A37FB0D397CA3DF9A98EBB48974F3D8A5E9812DC2E25238AD819029F58ECFF5133D6A0521944BD9EF95A45797CF5032614F0F88FE0F2E07B251CFCA247CBA3BED777EF37A9B4EDFC014617613A4D469D6E0102688FCDF8255596958EAEA19D0734E867FFD4C5508287ED912947EBFD19520E49AC03860D94352366EF8F7FD56BBF405571AECD2BB1012FDAD601FC063B92F1CC6EDCA99C80DF1619B8A2EC24BAA82CBA132060172F424C16BAA43A9D8228E500FD7197A87D22A8A72F8F3FAD0007C54CA676168D7B86FC901FD3B5DEA50D16124F8A70A2627EF87812172A7009A828F1FEC7EF8AFB5E75FF32439D9040F4B1654C7A6E016834C77B549C5CAF251B623D5B934F86743DCFA0D4B4A57DD9CF6522AC3BD19C3047790FD33C90C2B6E161C235438043FEB20BCAFBCC00D7519818C60F5EDAD8CDF80873A92BEE +ss = B5004ADF0D36CFB07BD259921AF706CC + +count = 28 +seed = CD6CFE94E9C0A1CC4FFDCD2D7876504BE5F50F1D1CA5CF93482943465B268276056F2781F4DE805C138976CA72621387 +pk = C7A15174B16833D563B47A3A8658A929DCD5413F80249CD506F1F8E345FE18DAED3CB4291F5064FC44BF06A148B05403CE1A10DD2F41018CFD898325DCDDF46484624317AB7883985F9FC31366F786A36BE40B7C111BC1AB71B61F5D763B625DF9C1C27F498F4C8EDAD8B17D6B015644608EEDFD2130E71F3D03FE9B1269DF2FCCCE385FA13D2EBB0EF6BCEB676121AA14B7FFB7C6AACF1468866AD7EAF31E3D2732C970001243989EB52F71577B978342CF0154EB3A46264892F9FE1D6BED6C0DF4FD626FB633180D3FD351C2951F5F063C2496931DFCE025F80500BBB68C8D4F7BEC39D56556181157D0E8423400CDDA2234B8F34329E44CEE0E8CC6D768284ECB20E5F797FF686D3BEAC587A7F5D99A8D01E57CA3ABAB77733ABA512507E69738E0DF9138CCD0E70A14617FBFB7938107EB18F47F536383CBE96316BBAC8FD787981191DD59B9CE00 +sk = 2E889F44E28901E9AC7CA6B2FFFCB124E0978A0CBACB4248BFD50609838543E787EA931800CADBE9F4A2D500C7A15174B16833D563B47A3A8658A929DCD5413F80249CD506F1F8E345FE18DAED3CB4291F5064FC44BF06A148B05403CE1A10DD2F41018CFD898325DCDDF46484624317AB7883985F9FC31366F786A36BE40B7C111BC1AB71B61F5D763B625DF9C1C27F498F4C8EDAD8B17D6B015644608EEDFD2130E71F3D03FE9B1269DF2FCCCE385FA13D2EBB0EF6BCEB676121AA14B7FFB7C6AACF1468866AD7EAF31E3D2732C970001243989EB52F71577B978342CF0154EB3A46264892F9FE1D6BED6C0DF4FD626FB633180D3FD351C2951F5F063C2496931DFCE025F80500BBB68C8D4F7BEC39D56556181157D0E8423400CDDA2234B8F34329E44CEE0E8CC6D768284ECB20E5F797FF686D3BEAC587A7F5D99A8D01E57CA3ABAB77733ABA512507E69738E0DF9138CCD0E70A14617FBFB7938107EB18F47F536383CBE96316BBAC8FD787981191DD59B9CE00 +ct = 1BFF2F2830A933A56F9AC4173358755194C458861D8C6C73AAFC1CC08CA359ABFE0E30330BBE6FEA2D0544F3742E933AA1C4D9AC2BAA000820C188A30EF5D9756B0ADF2493591EFDB4369F38DCDD22B23855074E70B6C8B44CDA713ECC8B8E28CA62F50BEA5D50A5D783CB90070134F6D4AB28ABF2E5F819153ADEAD5E66CA1E3B18C531571A063C06A365E359C90F679ECE5E70E9CAD5EF89406CAB86BA04BF78A53E2401A1BA6E6612AE8995F32DB213EAF58ABD0DD58680F7B922D3D5CE2B584E1AD22D45C252C806CDD0EA8D7C2CE6FB82201D61F2BE039C780069E916EB58469BE7B780E73C6501C0739374B5080DBCB4C88C08E95ED5A85875B722C611C8CA22AF9743142505E36AF325D46CB5D8810001A1F788627AADD7B697485CBAAFEAA1BEC48B3A9EBD60DB6761637B83C889F46D4428560C9902F36794FEE7B015835D6CFB9853A43A019350ABCCE41278B4A884C1B57C18196F +ss = 4F8AE0D0BC2AA3FF8717C6C7A876924B + +count = 29 +seed = 265EB2DE7099E4BD5614E5DE7F0C2A05C78EF3E8E2DD4AE4CB70F3E5E59C8D1D88248303F07DE0C5508652DA66B47222 +pk = 6A534BF74C6D58027DC079040D66CB118F898B435017BD11F10F5C17209EE5622DE035BF0D9B7754571173F16764D64BBBB00C6D577C0174476727253EA41211FA32F2BEAEBD9BF9D7D1D24DBDEF9326ED807C726394E0D5F70A6E9C2FD3536BA45AD16A1E223262BD85DBD992007DC4F4AE07D9E8B460AE2D1D6C94EFC898FC4297E603901D15E2B17C0D73180E9BBCE6B0C373780744BF3744161926C53BA18EF2688601D5AD8E623856809A460AB077C813D28FE82A8D91DB0830991047EA507E64C7000A8A89C14119846A360CD4E3D8A9EEAC984710FC5C4001EA827D32416068CCA6E666E1CF610B6BB2CE58E9A85B99358C0F1F9B3CB1C10D53D2EE9BD68A6625D24857585B36AE1E53D7E49ABBAA0074A77FB1AB394A13D07EE9C42DA45935F4CF5A726EC71FC68A2A181F508FFD34E4AB07D786E9A3662176DCBD42FAD52EC598366B796100 +sk = 174AAA36410566DC15A5E62874218D7A654BE8CCF785304172D23662455A07E51DAA8BB66E6A7E64506F3D006A534BF74C6D58027DC079040D66CB118F898B435017BD11F10F5C17209EE5622DE035BF0D9B7754571173F16764D64BBBB00C6D577C0174476727253EA41211FA32F2BEAEBD9BF9D7D1D24DBDEF9326ED807C726394E0D5F70A6E9C2FD3536BA45AD16A1E223262BD85DBD992007DC4F4AE07D9E8B460AE2D1D6C94EFC898FC4297E603901D15E2B17C0D73180E9BBCE6B0C373780744BF3744161926C53BA18EF2688601D5AD8E623856809A460AB077C813D28FE82A8D91DB0830991047EA507E64C7000A8A89C14119846A360CD4E3D8A9EEAC984710FC5C4001EA827D32416068CCA6E666E1CF610B6BB2CE58E9A85B99358C0F1F9B3CB1C10D53D2EE9BD68A6625D24857585B36AE1E53D7E49ABBAA0074A77FB1AB394A13D07EE9C42DA45935F4CF5A726EC71FC68A2A181F508FFD34E4AB07D786E9A3662176DCBD42FAD52EC598366B796100 +ct = 22146D9D609E135591109A291F87AD1FCCC007F32031320F78EF50765C3EEA95EADAD255777ACFF05AF66F56304933B295353998CF7700A56B3B419F55D09C1627CAF5B23681D71E5E7892B9111295C46B8E97797E3F825CFDC17B368656E7667E2F83CB48F443EF426609998F01403BC546A41DB2CD1CF3EBD576154574E07E23FF8E2CFAFF96D73B458C2E1E0FE3054E0489FAF1DC79FB98E0BF3D49B88E25608A2AB50155C5CA6C080FD21A2A21CAD3B589C0A17F063C7BA4A0954720CD511EB8DA27B298AFA32FEFB1FCEB49DAE3170545609E41A5E72B98F801E15B41BB62543E8B7F6187818146E2C947BA339190E8B83AEF1D3E2D450DF00C14505BBF947C1479EFA96D0C88E6ABD915ADD43867D0017FB5B930BFB8C90EE21D43705696C7D93C1687692AB43F46E4316BB1726C9BD6CD9918BD7E0C24A7A9CC33A40A6BABBC0BF23BB735190064509F719A8623890634F6324517357B +ss = 0DA2A1D17AE0CDE68A74B4BF76ED8D71 + +count = 30 +seed = 806BBD111F27C2668318387BD0830F65EC21A51AF01985EF48D03D64E1958FF7EE5133A4EBF6DBF36329BCAAF65F40EA +pk = A63B2A28909178A9D24BE5939CB25A530E8C9F55344D6F9AA661576D70C7EF5BCC59B76EA915AA0258584EF18FF65A8240321C1AA56400CCE0E2A91E0B439A8FC9DFD2A1861D064B4D3B72797A19874DB3B9339FC88E2E9EAE1945D9DF5837B1B40DD4BADD7A1500B971BC5D9B01F40ADB8F44009C2AFA75623F354F251EF76C0BF0176DDF9E2D87CD3B3FA3839C937FC8874A8843F87726178A689267C1F665D9EF64C5012C5D8F33DF7E9D0FCF7C878E5B2F67277E6FDB402955D65B015269D318F3E90698020D4BFB8B39F5FA0F0F1D76B102B06EFC7FD08B9C017EB568ECEDF74AF679187989FF1187511E66E557B391EA3B899993498B7B54EE052472381520F798539CDAE2D3E708210555F518A1D301AFD7E2C5108AA200BADAA1189F0A53EB49950CB292E36C52CACDC6389A19B79AABDD247738EA94A76C889BFF89F93191817B1EC61AF901 +sk = 351FE4313E2DA7FAC83D509F3103CAF7F33C7F7BCFF9B8E2D0728777AF71AA0254E89D9867F83BDD2B008C00A63B2A28909178A9D24BE5939CB25A530E8C9F55344D6F9AA661576D70C7EF5BCC59B76EA915AA0258584EF18FF65A8240321C1AA56400CCE0E2A91E0B439A8FC9DFD2A1861D064B4D3B72797A19874DB3B9339FC88E2E9EAE1945D9DF5837B1B40DD4BADD7A1500B971BC5D9B01F40ADB8F44009C2AFA75623F354F251EF76C0BF0176DDF9E2D87CD3B3FA3839C937FC8874A8843F87726178A689267C1F665D9EF64C5012C5D8F33DF7E9D0FCF7C878E5B2F67277E6FDB402955D65B015269D318F3E90698020D4BFB8B39F5FA0F0F1D76B102B06EFC7FD08B9C017EB568ECEDF74AF679187989FF1187511E66E557B391EA3B899993498B7B54EE052472381520F798539CDAE2D3E708210555F518A1D301AFD7E2C5108AA200BADAA1189F0A53EB49950CB292E36C52CACDC6389A19B79AABDD247738EA94A76C889BFF89F93191817B1EC61AF901 +ct = E5D3BDCF2887F16B012B17604096FA3220992E756D23081D0DA75BF7A40F196F3D370AC078586AA613477F5F60100A6651DD333BD518024FF2655609A5D8B82ECEE75ABD75496E90913323E385526509982D861C2AAC2E4D096E3793A8E9609CA1BFA1F9BE8C3E74A858C883A70108C646486719961CFAF18DF04B6F821A9532935894AD55A47CB3573D58FCA9AE6B5804AEF6E9DC6DC1E1B94189CDE10BB5A84182DA2A022560A933D838F293E427DEA7B0AA2AE25CACAC1FF483F907201F947E209A32D3EE86956371582B458A28C76B91F13E2E8B2D3D0BF2D1002586E5A9834917B943539EB3CF993F34BAFBA9557647D0518A189FDA12C04979229257A4BBAB34C9CF659C80DCE1D03DEF4793BFA8C10055FD41D06B629DB8178F8CDB33F7D1F5311BED2B8A6B9ED38F1FFAD72241552E5D06F44269172D25E1A5DB64A285B13C924B2C6B90D6014F983A2E3F8C63E8FBFAD9EB68794174 +ss = 5B0C71C6C97FA1FFD3A31B6598B80749 + +count = 31 +seed = AD540A9CE816D6FB1661E5483C44F6FDD00C9E7BD1A8CEDA4B4C4D3697D4F78ED0A56954996CCB7DA96ECB8F5CB15809 +pk = 67BB9A00D3AF1BA186ABFA6C21BD46DEBA00570578F03C5CFF05B5CA56FDC4C1A616D6841799F71719D1DCD1DFA3799EA0B5C9D3D004001160B669655F448C6F9FD30C7B985802D0738F0447FC5B3B587B0DAC305432BA8EF5937CA4BF3704F5F08D64CAECCC77D9CEBAFB2DE401A48B0E89EE1E8876A8AD3FEF2FA6081DD522ECD1B1E100EB67536F62591EFB339A0C7CAD7FB70B9D1E7F8B4661E4C1A72C9730112A0901061EE3F466198FDFB528715224152BF0798C92775865F6F08002BC7D89E85E1198DA17FF0EE2E0D65DE16E3129DE09EC260764980A3E01D9F260F81C21E257974FFAC3B31D108F4D7648F1E5B26C0068669582D03EDA60842C8D1E14C92E51A7EF5DC9D7196654C4FB312C15A401013BFE48BE05AB9E8CC633D5C31CB57F6BCD3A8031AE973C9EC8AB84CB97D3062DA6A0D19B0AC0AE4EFEFD5D8C17DC99E8D7B1D694E000 +sk = 9BC5315580207C6C16DCF3A30C48DAF26D9E884BEB0556E1A5F29C6DC5D1EAD767E59BAE46496B40C790650167BB9A00D3AF1BA186ABFA6C21BD46DEBA00570578F03C5CFF05B5CA56FDC4C1A616D6841799F71719D1DCD1DFA3799EA0B5C9D3D004001160B669655F448C6F9FD30C7B985802D0738F0447FC5B3B587B0DAC305432BA8EF5937CA4BF3704F5F08D64CAECCC77D9CEBAFB2DE401A48B0E89EE1E8876A8AD3FEF2FA6081DD522ECD1B1E100EB67536F62591EFB339A0C7CAD7FB70B9D1E7F8B4661E4C1A72C9730112A0901061EE3F466198FDFB528715224152BF0798C92775865F6F08002BC7D89E85E1198DA17FF0EE2E0D65DE16E3129DE09EC260764980A3E01D9F260F81C21E257974FFAC3B31D108F4D7648F1E5B26C0068669582D03EDA60842C8D1E14C92E51A7EF5DC9D7196654C4FB312C15A401013BFE48BE05AB9E8CC633D5C31CB57F6BCD3A8031AE973C9EC8AB84CB97D3062DA6A0D19B0AC0AE4EFEFD5D8C17DC99E8D7B1D694E000 +ct = 4707B9E7C15985BA3D1097262E30395679522860AA06FB66BBDA9A990CC5647D58AAFF212730476C1FCA15C84C576C7B49140D58ED1D004F54548341CF3D64E4A5CFB19C605CD3A97FA403C3C032DF127304C0654AEE6D9F55E2CE651C422C4D7DB5346D52A17905F2CD8F4461012AAE335BA0696315BB4EBF395C40E8AEB859B45C55B0B7C65A6C5D7A2A48F3319112C180FC45F52B5429AB8440BB503350BE33E8E2FC015353963D816FB379F7848A61057FD5946A303E26717F250C8A4A542347EA3E8FA95CFF6ACF203960E33313E04C4D08C5C9ED156D1A9E0116961A32E78446A217D6FBD7B65125B5EE1BB4803D4F65A83D169715F8425847584CA8A122460071AB06A1CC9D187E351E78BAAA657200C86564E849C8337689605EAC9C29FA2939C427AAF6BBBE1A176D8FED4F3C8974B0992C16D145583C0CBB6CB9818D19212A7147AFC88A01281AE8B5D46550C2D9D2D86DD70FDE07 +ss = B566B8997380CE9ABBA5A871A09D934E + +count = 32 +seed = 288A5F2684D862A86D2790AFDDDDBAC6FDA934EE7D2E6DA1508BB550838609E8107312B28E00A6C01706374CCD3AEFA7 +pk = 6DFB6A675AAC447EC0AD5E53EC7041616889FA9E456E7A7D5456845D9ABA80354DEEDB58BCC2C581B74A32D08B8D0F313ED53E39EF8000F8B1737504BB222F60A0B45A7CD9B1FA41BA53EBAD6ACA23076335B57DBEE7BE25E724FB787AE7B1A0B65BCC12ED1D4B8D232EEC0FF4013BDFAF510A82DBB2733683C67CC466ACA19CC11C9C0D1FCC32A60D5FA7AD360A0444849CDE6F05EA3412BC61C372F30C0F0A3D03011D0064E69B5D94C915B615373CF5E3F01FCACA7C3480B1C03AECAC80739084221AC550A3D91562C0C2FC339ABB01ECF8A19F4346E1853E89014209997CDB1192AA136C34859C37A093D23D4D3174095E7563CD7BEAAB20946F2F2C2207E763BBAD441372CDB6A457B5BF0F67FDA3C5008ACEDAEC5418ADE37EC5A0346CD06A130CDB15205D23E2065A0E1621DB5D5794C9D83DF48D006C7DB8949092AC1C29BD8CD15B8D212B00 +sk = D8B907B34D152FF8603B73051F772DAA4713480D2B1C408532CA1492DC73120EA013E3522323EE18F2FB4B006DFB6A675AAC447EC0AD5E53EC7041616889FA9E456E7A7D5456845D9ABA80354DEEDB58BCC2C581B74A32D08B8D0F313ED53E39EF8000F8B1737504BB222F60A0B45A7CD9B1FA41BA53EBAD6ACA23076335B57DBEE7BE25E724FB787AE7B1A0B65BCC12ED1D4B8D232EEC0FF4013BDFAF510A82DBB2733683C67CC466ACA19CC11C9C0D1FCC32A60D5FA7AD360A0444849CDE6F05EA3412BC61C372F30C0F0A3D03011D0064E69B5D94C915B615373CF5E3F01FCACA7C3480B1C03AECAC80739084221AC550A3D91562C0C2FC339ABB01ECF8A19F4346E1853E89014209997CDB1192AA136C34859C37A093D23D4D3174095E7563CD7BEAAB20946F2F2C2207E763BBAD441372CDB6A457B5BF0F67FDA3C5008ACEDAEC5418ADE37EC5A0346CD06A130CDB15205D23E2065A0E1621DB5D5794C9D83DF48D006C7DB8949092AC1C29BD8CD15B8D212B00 +ct = 17DF50A3C270E4A93FD35EA23A49E81CE417672C810937716341B46C031E5D09EB90FC53D11605DA1D1BD54DDAD45784EE5B3699CA76015173C9FB0C94EA1F6111D36CEF2F13C6EC8A82C4C42821F96C4B2BD4BB88A83DEB6EC0CA05CC8129D4A984166983D55E41CE49B49B910148EE6D6A544DEB5129F3EE98FA8F210C0FB3CEA00E03C3A478309454E02A1F55095973A4A1B06F06D9990FED792B07D1D9592480F04C00AE86ECFD37645FDDE16DFDECB35EA33209AD0D182338DAD6EE2871EE3C8C2500A16488F9F61819619D9BF578896DD7CDC0A6C1677856003463F823FA737A8518E5120B7FED15FE5E82F7958FB73EA0FF64ED569E49540F923EB1FCA63496013BB62B53DF43167AB110467B696E01ABFDE6E7CAA7C35F91ED0CE9C47901ABDB157B8096B98BEE035AFA5DD4F070A15B8D440333CE5874DCB14D2D070B34E12DE4A4D45A1D021855FA315DF1EC8955181B9A9B853830 +ss = 968C0162E93282100048613EF3C737D6 + +count = 33 +seed = 4635DC5BB92EF98CDB6220DF0DD717C7F8158375EAA2B78FC3F0B58E9C9653E92684CAD3461D9158A481DA3D14694C44 +pk = A9749110AE79832B23DF00ECE0D4DA13275EB4E2A42DB0FB7AC8A1C40371B5AD6621C11C10F9C385A2815572368794852DE1CE87C07C0179F034B5BC99D44AC64EDAB4BB38641C330458A21C980A08A63409FD5C8C15624A146A3EDB76B3823A34EF9908E0BF896F74D16529ED012E155F3542CC4E114A3289E285E560A576A9C9EB6D8B9561B85A7BE53FB368F535F605BD9746ACB7A0D8E0C6056A92527D5BD34947D101BD8D9FDBFE9FF72F6D5FD697A24455F46244EE0494B5EC5B2FCDC2DF02CF73D53996410A563A566FDF44E511ED855427EA5B4CF38C74019A7B9BCD6896822FA056CB7ACBC474BF3FB5098C1C1FBEEF23A438EB32848377516505F503A83DBF9758A863FA3CAC5C532F4C24491D01EB93C0752EBDFA3600F98B57393E766EA403A8E0BD125DBA0C7AA4F2827A2E10C6DCA2F3960AA6C981046214792DB12686F0A1FEB62001 +sk = 684A29E4E5480A5F2533E1526B5FAC8CD48C758346DBE432A3228952635DC682A402DCADB073D596FEAA9201A9749110AE79832B23DF00ECE0D4DA13275EB4E2A42DB0FB7AC8A1C40371B5AD6621C11C10F9C385A2815572368794852DE1CE87C07C0179F034B5BC99D44AC64EDAB4BB38641C330458A21C980A08A63409FD5C8C15624A146A3EDB76B3823A34EF9908E0BF896F74D16529ED012E155F3542CC4E114A3289E285E560A576A9C9EB6D8B9561B85A7BE53FB368F535F605BD9746ACB7A0D8E0C6056A92527D5BD34947D101BD8D9FDBFE9FF72F6D5FD697A24455F46244EE0494B5EC5B2FCDC2DF02CF73D53996410A563A566FDF44E511ED855427EA5B4CF38C74019A7B9BCD6896822FA056CB7ACBC474BF3FB5098C1C1FBEEF23A438EB32848377516505F503A83DBF9758A863FA3CAC5C532F4C24491D01EB93C0752EBDFA3600F98B57393E766EA403A8E0BD125DBA0C7AA4F2827A2E10C6DCA2F3960AA6C981046214792DB12686F0A1FEB62001 +ct = B456E8BB9C8D4CEF7EC7B5AE3D67F608C36227A26AA10CDFBD2E4CD949D586B0A60937D09329CE83EC8363FF1F8C171A2034FFF6E2AB00FD430A62678F4ED7E382CFB3A1D2E6DFBECB34B0862466D5D21CD281304CE0304606FA64EA45C98A8122CA453EF0C1DE69FCA2447E1D012AD5D1C153435568910F1580954143C5423DE782C493520A5653BD0009135A1665F46CDE58BC23841867D94A4969340F70727744212901F94C5A6B128C7DA96CE66B1D0BCA66AC33C3CE1995E544E99F0E410D5114BEFF28F055BE6EFD723F640CBFA035EF2C6538257D478B530040B8DEB4277217C80532D5F660BF3EC2FFBEC67FD6FFB78CF4684C637280BEB0FE6C0F2A2168474268AA46272A399F39EE282C89D91F014EA52E255432CEFC32FA7DC717F45A9820A5DC1D88B0F3763368E7F608159733BC18C8FC0CCE9A1621BD5E25B679DE75405EE853D11F02E2D0435B1B0494EF7CEE0546E49CEA0C +ss = 4CF1CCA95A4F53EDEAEAF084D0D6A0FB + +count = 34 +seed = 5DA2C51B4ACF488C8BDED5E985CC4702E4A7BCB248B5AC18AABA529F7F9CBF30EFA776E99F76D5C1686E94F50FB57DAE +pk = 755BECCBAEC71D99A39FAD1E7D64F741DDA159A12534D9E39DF3E4E5545314C41DDAB46F1045B275C02966242C3D077078F6668A9223014EAA908643BAF38B65BA06619F14DBB2F915FA998C31A36DF317BD75966B580E9DFEFDB8FB613664C95D00DBA0128B9AE2C2695FCD9401E0AF77F7539C14E0635893D3D0407BB82BEF1B14853EF1B79AD6A242B816761FBED743FC2F5758F53D21F583B2824E7BA760C84EDAB40067FDD800926EA6D5D0F434F905FB6980CCCAD6D1768D8F090779F8B5380A48B890DB4F81FFE52DDEB5EC1B9AA0D5E0960A9754496CD7018427DA38718AA3C54DA5CB81847ECC41BA4AA3FD4451EDB0759F2B4EDC24EEB22C3780B1A6CCB7C2EF5CD85BCE9A09B3B1331CF2FFFA00F790D58F7A3D0C77AB91E2BAD875648B34B7206D2B5DDF411569EA39713876F60D89D5FD724ACABBB8713303EA5AB89930B7DE87279F01 +sk = D76B3573F596EB286AB5231FEEC74996E8B7BE3C815A5D5D76C69722A85C212B66491CEF853A65710F3E6201755BECCBAEC71D99A39FAD1E7D64F741DDA159A12534D9E39DF3E4E5545314C41DDAB46F1045B275C02966242C3D077078F6668A9223014EAA908643BAF38B65BA06619F14DBB2F915FA998C31A36DF317BD75966B580E9DFEFDB8FB613664C95D00DBA0128B9AE2C2695FCD9401E0AF77F7539C14E0635893D3D0407BB82BEF1B14853EF1B79AD6A242B816761FBED743FC2F5758F53D21F583B2824E7BA760C84EDAB40067FDD800926EA6D5D0F434F905FB6980CCCAD6D1768D8F090779F8B5380A48B890DB4F81FFE52DDEB5EC1B9AA0D5E0960A9754496CD7018427DA38718AA3C54DA5CB81847ECC41BA4AA3FD4451EDB0759F2B4EDC24EEB22C3780B1A6CCB7C2EF5CD85BCE9A09B3B1331CF2FFFA00F790D58F7A3D0C77AB91E2BAD875648B34B7206D2B5DDF411569EA39713876F60D89D5FD724ACABBB8713303EA5AB89930B7DE87279F01 +ct = 65979FBC591F9A1F3C91C7490EA42D9DD744B2B2EEF097CE0DB5C92D29A08497E4F25455725BE66CF546597617B79874C1A6EDB7B628022C950CE48903F12510F76D2AC6412F76C055B00F118CE97FE4E7831FC0F96A41C48E148826B3360666F9B25F78A907FBD4EDAE5CCD0702919CF4F839F67A1456F9A5797AE632EA114B71915941AD1B29BCD7FB60431E6958895F9AD67E8024498C361A64662FBFD6295230C9C200D7A1DA8E8812BC64EB612A0742E1B4A97D9F70F42032B9F0C26BBD4D4527BC2DF82C023DE42327D7BE930C6CAFAE1E0743354338566101B337149C8EAADE6A00622406B137FB2096763C675DD4A9890F40F6BF5AD7D5A2AB1D43C4918BE9FDE65B06E20E15986BAA0B9414178700A8F3AB25B4EB2E78BDD626EC43A36C6931DAC802FB1CC250E239BCB7A28483CE6C2D568B6F4B9828B5AD5E6B34F88782A5C0B4E4B1A2009F96C663BB2FCC61E657BDC52C48C127 +ss = AE968D6A27804749820215D949802EF1 + +count = 35 +seed = 4D2239E84B052109A78DBAB6D80C51A86D38248105970476B74A0B78B9CFAB6283E30D5A406FAE1C7F54F8BAE1110EE4 +pk = B29D0563604551E0DDB53DC0F6A6A552403138B54DDD8F7E641439448B1066EDF1BCD01317A82A895EF44E3A551371BB6617EC37B5CE010B1DCA16216B1A666FEF6C072B8C36208F33736241CCEC4136D5000A3E1C5127C8F542616971D49C5AEB1337B758571E3850E3DFF6CD01ECEDA2EDC5B9DFD2B23B42062AAE93416478B4940ACAA7A0DF1D1217453FE11E6D59B3283A3C2AF9F7137704C6154F1CF26C478D3B9C00FE962821C843F08200B06DAD771C9739836B6AD549B0B929802FCD3F387676FB44E47192B708EFC1152D062565724CE1240AC980D2DD0136E5A04DE3694EF2F48279DF6A4E73DE70830B9C67E06B44A3A103E0BFCE63080316C1E63BC065C651359496379FAFB9FADBF2D6BB2A007F609405BBB86E0782A478D266800C9C950F08C71D28A55CD08575156BEDC60D4C111F83764B869892A1C710A23E655BEE1BC617CE2102 +sk = B87439FDE81C9E39EEBE7CF741C685789C1801C4A2DA5DE2C75FAD022D9418C2B6B82A2DE1586E0E0A31DF00B29D0563604551E0DDB53DC0F6A6A552403138B54DDD8F7E641439448B1066EDF1BCD01317A82A895EF44E3A551371BB6617EC37B5CE010B1DCA16216B1A666FEF6C072B8C36208F33736241CCEC4136D5000A3E1C5127C8F542616971D49C5AEB1337B758571E3850E3DFF6CD01ECEDA2EDC5B9DFD2B23B42062AAE93416478B4940ACAA7A0DF1D1217453FE11E6D59B3283A3C2AF9F7137704C6154F1CF26C478D3B9C00FE962821C843F08200B06DAD771C9739836B6AD549B0B929802FCD3F387676FB44E47192B708EFC1152D062565724CE1240AC980D2DD0136E5A04DE3694EF2F48279DF6A4E73DE70830B9C67E06B44A3A103E0BFCE63080316C1E63BC065C651359496379FAFB9FADBF2D6BB2A007F609405BBB86E0782A478D266800C9C950F08C71D28A55CD08575156BEDC60D4C111F83764B869892A1C710A23E655BEE1BC617CE2102 +ct = 7BDA080E55A57EDEBA01D4C5D1FF2451532CB5639322FCDE3B9BE0999AE0AE5E20FEBF6BF863B8D81141AEDDB6C0ADEE12E034FA122E02187A390D4B49A7C4BFAFB58D9FFCC65928C84E930713FBEFE543CF5F6CE14680198F900972947D80E797B0EBED4EA7846D0C053DE460019B5B9FDD36F2406C400675EF48A65B3ED760A2A6AEECB4A66A6E5F46450DD73F7B0B5AE57D5AF0135B85A9EC168D64123A7C66A854170081BFF5DC07ED5328A14AFEBD01D839F95C6D1B8D9812D37F2F432379AD718620C7F602EB6D662337A0BFE90C9F49BA00CE1F5035723301D01C6317A783951674E2868238AF6735549E1E54CCD5B931A94FE6FED80B62CE244670BDB33874A6D6570C2B2E029472A2F5E298734100E47133378E7D58E96A03AD5CE897539D30FC107EA9C70938A4D02235B8F088C76EFBBD7B7F647EA3BE9DB150FBACB46E75CD97CD30B600171A71D988ECD50292B6326C3E70AB44 +ss = 106D77DECF74C78D230AE3A4C60E9209 + +count = 36 +seed = EE762F5C9021C36446706A88EF16312F4A12C725CD7AFFF1484337C91EDA8E89F7007F3705747D29907B3FB7500E5074 +pk = B670CDC458CF6AE732F6CDDE24E56BB2C7AD734022B455D5DA50E9BB19E15DC66BAABA217B447D8A7930E018E605B1F5B7D4C628C5160264BE68A1103225A206033E82366CB0F2105CC94694868735B0C98738F9F218C5FDD6B97AFB2F0575628688098D55AB33893135B9C9820078F7874F2B13D3A810385EB80B906030F11599CA82FFFF99E03BAD0B2427E59BE6E48ACF88A56190CFE764F9D5E17368A273A475C9A101E15D87649E54B874B22A7792BBAB6A48A7A63832FC14C95EEDA92DD4D156D7CBE576FDCAA4C446CF7C93B79A04123EAF6D2F6EF26C5C01886FE3BE92A8D6CE49022A15005DECCBA8E14A2FF80E62E3E09925D353CD444A78DD2FB9265FA53DE75D65564336F0C5E787C703406C01EC47BCB352A6650A125D04D3A43B6DDC8AA829B5CC391AC21E394097516EE56635179A32279F43904DBFAE7C03D3A23001B85DD0ECAE00 +sk = 056661B38038DA4FDD7426F32A81576C9B4469FEFC4282E5E4563F98349656F19BC4B038D90BBAF3E534DE01B670CDC458CF6AE732F6CDDE24E56BB2C7AD734022B455D5DA50E9BB19E15DC66BAABA217B447D8A7930E018E605B1F5B7D4C628C5160264BE68A1103225A206033E82366CB0F2105CC94694868735B0C98738F9F218C5FDD6B97AFB2F0575628688098D55AB33893135B9C9820078F7874F2B13D3A810385EB80B906030F11599CA82FFFF99E03BAD0B2427E59BE6E48ACF88A56190CFE764F9D5E17368A273A475C9A101E15D87649E54B874B22A7792BBAB6A48A7A63832FC14C95EEDA92DD4D156D7CBE576FDCAA4C446CF7C93B79A04123EAF6D2F6EF26C5C01886FE3BE92A8D6CE49022A15005DECCBA8E14A2FF80E62E3E09925D353CD444A78DD2FB9265FA53DE75D65564336F0C5E787C703406C01EC47BCB352A6650A125D04D3A43B6DDC8AA829B5CC391AC21E394097516EE56635179A32279F43904DBFAE7C03D3A23001B85DD0ECAE00 +ct = DF9CD952C12F9F05F73D441464A18B05771B5CCFCE4F1EDC33FDD3C5248616D0BAAE63FD10F117B59D7C892A525E84FA84CA1BD8D5F80119BDB8BC3BC3876F861FD8DE0AF96E6DE0827B7C49A3E1112E9231FBE4390BD8C65D6764ADA84F88A5881BB17DCA90579F71659D329B01BD3DF1FC018AB7F338500B599D05A57F89BBA5DFEA91F1765CE2DCE25AFE7A2B760856D0ED46193EE78E8FC556E28117D3B448A7F56D01D37418D88820ECACA50658D4C6AF100BAF9ED5AB79CCEA0E6347D51533DCA2CA50EDF5812FB4CC5F5136AAD41EAF97D483A4BD72E40801FB36D31ECBE3371205E1076B343781AA0257D196E12A60BAE0E11AE4964B49F8FCCA81393472BF8E9A48842918793137EE5DDDDD11640170B17A9307A7323AECCBFC1D24607B5A9E67018AA17387863F04EDF2426D23E435234EAEA7695B092DF99A11FA5E08F5B3CE61787AFC00CABBB865C815ECEFFE9E5F90B1E14DE8 +ss = 265DCCF5815CF483644326C4BD905550 + +count = 37 +seed = D882BA69AC8BBC88715F1C6387531F53273A5DAB87E66FAA8221A7F628D2BDEEE1CBC59C0E08D0ADD84520A3A70C1389 +pk = 23E28D43F846DCCC539A3DE1864657579B9DEDB6CCB6B339E2F181C9F4FCCDCE9FC7F3B40F92C5098D78A68F11837C0A7BCF44D26E21014B0CBCEBB86BC92D8009A7CFF8544B4116EA1518679BEC46BF11B8C451FFAA032B1AE58B91D9C2E4D5489C77BC6E5853E4E6BB9FC7FE0199BFBA3177BCB574502E5D07E81867FD7FFF2F0C2B030996D5629F80FF4F97BEAE55BFF4A3E5593D07FCFDEF632D609F1ECEA9AD727C01B5B463C7089B6CE458002F488F16773DD2FB6C838D39154AE328D55D48558397C30F772B44C4449C5E6E6BECD46D6AF9F1C5ED86CA4700B666AD1153D4DF7E75CE07C0965383B2EA85A1206BF2CAB2A18D1BF9233212792DFD7C4FED46D9E7B11DBF9ACA42FF5A0696C26AEF6500BACD4695FC2D8189D58FA5D49C0ABA66E1255D15794D2168CF72B357CCD1923AEB384727A48EF43B3EF80DA1D994368603FBB370405301 +sk = A1B52D871612A1C611AE0944F9E718585D189DC4AC1BB9A9329D942E322E0175D03AE93B11DCE9CE0046DE0023E28D43F846DCCC539A3DE1864657579B9DEDB6CCB6B339E2F181C9F4FCCDCE9FC7F3B40F92C5098D78A68F11837C0A7BCF44D26E21014B0CBCEBB86BC92D8009A7CFF8544B4116EA1518679BEC46BF11B8C451FFAA032B1AE58B91D9C2E4D5489C77BC6E5853E4E6BB9FC7FE0199BFBA3177BCB574502E5D07E81867FD7FFF2F0C2B030996D5629F80FF4F97BEAE55BFF4A3E5593D07FCFDEF632D609F1ECEA9AD727C01B5B463C7089B6CE458002F488F16773DD2FB6C838D39154AE328D55D48558397C30F772B44C4449C5E6E6BECD46D6AF9F1C5ED86CA4700B666AD1153D4DF7E75CE07C0965383B2EA85A1206BF2CAB2A18D1BF9233212792DFD7C4FED46D9E7B11DBF9ACA42FF5A0696C26AEF6500BACD4695FC2D8189D58FA5D49C0ABA66E1255D15794D2168CF72B357CCD1923AEB384727A48EF43B3EF80DA1D994368603FBB370405301 +ct = F0AB3E2C9CCA0E67AFE1AD0FE8C1AC6D2938CD9E14207FD02D10F8A737E0FC51B0439A80BB67FFCDD3B7883599CCE68F66B1113E458200664C0DAEA094057B1F5166363F0B8B36AF4504FD08AB43FCA8882904DE88E8E775204907D194D4AA1663C936F2DB4AC3A6B2E29A6A4600A5496F3C98F745839A013173DAD4A763D7B6E1F8B0BC0F46DBB3F9D920D4C4CA1A982CFE11B25F2BBCC1F567D8809EA66842F3CF140B01854690C5D960168883B5F0B995355305818C841BE63CBF645A89693327EFF6BD27A4B4919EB654011288499A49DAA4B12FF6DB55EFF40002A360D34EFAE47C45380D0226EB9144C2F46F8D68CFD914525DD4E3FEFC9A5284F3260F3BC292D9BF3E0C701420C1D5B57EA5B0AF08006986371BE0AB510DB5968950E3A9B3A05116A40CC5A58CE8E0B04CB1E0E010F72129D2049D3844B91119DD2EC22F0F5B4E0DBE75DE1F016D3B7508B73A7F329E218E70D8A2F1A8 +ss = E3A35F1CB2667A2FFDCE38CE2FE22205 + +count = 38 +seed = 6C3AFF39F5D097096D882F24717718C8A702382DC4AAFFD7629763FDA73C163CF084807BBB0C9F600CD31A7135F48AEC +pk = 2ACED76575102E9CA0AEF82D980EAD88889D4BDD5D5434D7EB162309EDC1E6619B90AD83AFFBDF90AC0DAE4DF4B00FF4B63A96ADA65D004AC8423058F244A1BF4FF112F396D82C15E6835414BF44D56DE3C5833D9267A737B48009A6EF15E8BCE9893195984CD94E2319BCB08500DE313971527E4B6AC7677B654C8BCE46AE14E0E4BF705876DED05B5EB478068663FED13EBB045FAB2ECDD92124352E70BD7F84B3C63701376F75BA7ABCDA55D586397BD459D8F6D2EB06F16425293E10E86CC9AFD61F41E04493338699FB43423F769DC2D2EB9C2F4D1D6D1B8B01530FA5577E4483BC912ECCA04170B76D25EC70646085C1C56778DCA20F4874A384710220FBD562F0409BA6E866FFCE374CA3431494B2010B561D3491A746C031DC7FB712746C0D4DF6D6738C4D78E84C7C9384C62BFA8CC9DC598993E2EB2E2BA0D10AC3862BAAA9B4725241CD00 +sk = 952B49C803D6D6FBA69F4375ADCE8594D6D0ED89E743657C260B769DDA95968B08C290D0B1AD889BFF66CD012ACED76575102E9CA0AEF82D980EAD88889D4BDD5D5434D7EB162309EDC1E6619B90AD83AFFBDF90AC0DAE4DF4B00FF4B63A96ADA65D004AC8423058F244A1BF4FF112F396D82C15E6835414BF44D56DE3C5833D9267A737B48009A6EF15E8BCE9893195984CD94E2319BCB08500DE313971527E4B6AC7677B654C8BCE46AE14E0E4BF705876DED05B5EB478068663FED13EBB045FAB2ECDD92124352E70BD7F84B3C63701376F75BA7ABCDA55D586397BD459D8F6D2EB06F16425293E10E86CC9AFD61F41E04493338699FB43423F769DC2D2EB9C2F4D1D6D1B8B01530FA5577E4483BC912ECCA04170B76D25EC70646085C1C56778DCA20F4874A384710220FBD562F0409BA6E866FFCE374CA3431494B2010B561D3491A746C031DC7FB712746C0D4DF6D6738C4D78E84C7C9384C62BFA8CC9DC598993E2EB2E2BA0D10AC3862BAAA9B4725241CD00 +ct = 46722EFE47F4BFDC5B36F8FDC92336C965669E48B6A1018E88B4AFAF4EC7765AF9ACD146F2D0DD800BBC15B8A79043E74DBA8372DA5E0157635F4C61FEA89934E5948B39B2C4833DF9BBD41A92E87D2EAA03F892FBE46D5A3DED0474FD123B6BC29A6D451F0C4CCD913994BD1900E3164E578A596DD8E7B0C6EB7A2485113A8AD5770BEECEA55E302039658E234E918495E0EEAFED4FB8AE8FDB0CE0EB926075C4E5EB4B00B57C1643BD1B4166191A35C0DCC839FEBB8B4BE072452C5BF0E901D34A71350BAA7EC471780306856FE952C97668E94EACDF943047870093BCF560CE4A01C0F26C9B4ADC2B7EFE2C97D9FA8C38FA193A61D50DC4DC4CFD09EE9F3D4025F51231CDEF2D1229B4995274B3EBDD5B01849C10CF45ED4C2EC1BCA8C03A0F0619FEE9FA84095D9A95CDC957450BCB5B3639076A6D6117922D8998BA479026F050C1A9923FEFBD009C4DF016F2395F2C7EFC8203AAF18A58 +ss = B58E59F4A05558B84AE4851836CC49B2 + +count = 39 +seed = CF520B92A2E3677AFD003EC1EC6EF136A709D78F828C9C0DD4946EFBD451C5FAABFC83CA66F9D3D17EE4220553B7A69F +pk = 0F0B839F996D4D1E8F08AFA3A1EFBBFB28BE9A35E187F27431D48D05220A98DF798C2432C2B28D966B8806E83F7C6DDDB9AF95FDF4C90088D311DC95BE43024AC244A1ED221F16153D6BA687EFD5A628918209F869DB38BFB2C44C95F5FA8753CD350E09C3D5DD1455EEEE4FE90006649D4839FDE8B88029AB779D48479080558FD4DAD1390C981CD7CB30FB82342344A52AF58F076983F257B1E1A1062B79D62C32737B0109FC20E92E9A264825E8B477A50B41157F1928A94596CD2D65F3386CCCE7907E9CFDFB78BD9718C1F6DE7F87150F3BC8E129BDCF093200D63A1F74F38C77C903E67C3913CE22E7B879DF5AEE80FC7D1C52E6380F9C715432A326DCF451446C90BE35D1DF2CA71E1E85814CDBD4014AD1F145E161AC634CD22A3276D8073377F40AFAC4166EC55A434F8BCD1A55F5FB7C29FE35A6460F245F08B67846FCCBE07559CF19D601 +sk = 3C815E57E9233E975FA1630208AAB206BC7309AE5C304D142AA66EFB4C844C6071BAE44EF96A27ECCFB6B8000F0B839F996D4D1E8F08AFA3A1EFBBFB28BE9A35E187F27431D48D05220A98DF798C2432C2B28D966B8806E83F7C6DDDB9AF95FDF4C90088D311DC95BE43024AC244A1ED221F16153D6BA687EFD5A628918209F869DB38BFB2C44C95F5FA8753CD350E09C3D5DD1455EEEE4FE90006649D4839FDE8B88029AB779D48479080558FD4DAD1390C981CD7CB30FB82342344A52AF58F076983F257B1E1A1062B79D62C32737B0109FC20E92E9A264825E8B477A50B41157F1928A94596CD2D65F3386CCCE7907E9CFDFB78BD9718C1F6DE7F87150F3BC8E129BDCF093200D63A1F74F38C77C903E67C3913CE22E7B879DF5AEE80FC7D1C52E6380F9C715432A326DCF451446C90BE35D1DF2CA71E1E85814CDBD4014AD1F145E161AC634CD22A3276D8073377F40AFAC4166EC55A434F8BCD1A55F5FB7C29FE35A6460F245F08B67846FCCBE07559CF19D601 +ct = C83D91157EB6E5B5033B430B8F1004578C73134349DD120B8AC29496C2FA5C8762029E057FF023FE6BF3C02228B516F7E6B27444672C01DCB6021EE5D705EE284E2E592E99A8B327BF181E3E48036787BAE959AA50CA0A0E20773A555E7D9DFD4EDFE674F01D3E2C9ACDA45ED3008D414FFC10DB82EBDF5483B1A5E2A16E134008FEDCEABAFA830755321BF9A14FD218F3026B9DE3A69FDD6F0F5BD5FD2DB637C281E4AF00D5AA853CACAB943252021EE2CD55F52FA5D6050717ADE74242EB1E1546B3B02E0DCB4E00A7525351FF759732733E85B6D33D40ECCB0D028FB110F1E5BE9E2B2B6D7C87CADBA3EE50DBA37FB380C45B59F6D6242A4A7D8A3FA1554AA76449750C19C68B0CDD508533E86C248DBA0178935029B1149D5A256BB1E9A7AB0EC4E997DFBBCF88A89462BE9390190BAA036F166E9FB6CAAF0B4C3A005FC72AE5CFE99E74561EC50176F046B69E8F6ACFCF6C7E4143917652 +ss = 2F93D724C4655F62C3BC06277EFE84CB + +count = 40 +seed = 197E5D562DE7E01BED4FC597DB28DC6EFDF0179F3A5BDA5F94CAA39D67BAE730540534D59A7A06C8448F628DA8B7859F +pk = E2EDE84A8108232087E95C55D274AE9E40CFE4DC7815504CFF0C92D4AE62A53C6C42F1D7B45200B285478B34C6EDEBB5FDE3B68F6AB301CA6ED9C94F64C3F7AA9E5AC02E42BA75700D9F38445BA4E2FDA972EC627F5EDDC7145D8A61AB88A61561BC186EC67BAA7C706E9E0A8B005A4D7255622337F47C5C871F0555689EDEF50C61B3230291F27740CF64102B44334D37EB4B060CBD0BD18E95563ACDC4D8B314D6916001339DF3B4CC6469F7B426FE2D83D1A077167B61ABBD9382756A205A9D55FB54FB66FF30D6622D0700A28039A1F4083486171C119DA5E9002855AEF2BBBCE4EEE2B68E5F8837AD3C00C6E63D589CC5E14294F647DAEC7A8A9B9A3FAF8E18924255ED256500ED539030FBB9D3B93E007F301EE812A7B486B903326AD035B98AD887CEDCA58E6C1D8E1351D88551FECB51334396232B4E595FBF54699AD1B72E1AD5A54BA20000 +sk = 588760826DCFBD36D9ABE6AE44A669BB8637FC0C04E21E7629319A89BCDF0C2688D3F3C62E3DCB1FB5C67E01E2EDE84A8108232087E95C55D274AE9E40CFE4DC7815504CFF0C92D4AE62A53C6C42F1D7B45200B285478B34C6EDEBB5FDE3B68F6AB301CA6ED9C94F64C3F7AA9E5AC02E42BA75700D9F38445BA4E2FDA972EC627F5EDDC7145D8A61AB88A61561BC186EC67BAA7C706E9E0A8B005A4D7255622337F47C5C871F0555689EDEF50C61B3230291F27740CF64102B44334D37EB4B060CBD0BD18E95563ACDC4D8B314D6916001339DF3B4CC6469F7B426FE2D83D1A077167B61ABBD9382756A205A9D55FB54FB66FF30D6622D0700A28039A1F4083486171C119DA5E9002855AEF2BBBCE4EEE2B68E5F8837AD3C00C6E63D589CC5E14294F647DAEC7A8A9B9A3FAF8E18924255ED256500ED539030FBB9D3B93E007F301EE812A7B486B903326AD035B98AD887CEDCA58E6C1D8E1351D88551FECB51334396232B4E595FBF54699AD1B72E1AD5A54BA20000 +ct = AFA49BE5FA86BD3317A0DCB7B86B38B8A585B3D0755C127C6AF2CC1CE190363B0F40C14DB8B7F426D800348B2C2D0BF39788166178C90199BA184F96662741A6592D1FF1E777EF7B9AC68402067CA677243CAE3A5116A270C4A6362228DEE70595C4FD39E7F906C906BC36575E018814CA8FA5D7D16E0B75E1AD4E946EEF64D551769E00B7A58B13436382E0AB82A5759349EAE99A69339193DBD0B51115A3727CE689050155A5FE08145441C60C9D36A81E47DA6D1872B914D64BA1C8DB53DA264453A5E74A8B14D6401710069A9CAB211CA4C27964C94A69EBEE014EF1CB1743F35093C33F3692F13859955B2911CB6FDFDBB7CBBBC164FCF8772DC09EE0756C822269FF58F1A2DDF6273893228658B0F001DA2C9E0243F750B0C4E231DED2B56139938B079B2D9FDCF9198806689D4B6CB2659A28197C2BF4A22CE9AD87DDC2D2B54593703C1E1A01C3F0DE7422029F4E69CA6F91730C37ED +ss = B899E849D60739D059CF343F459E7230 + +count = 41 +seed = F170583CB451D8A45D105457C02C01A33A40350616ED8515BD49067142F61EFB00F07857E4FFF3FE11E7164C648C76ED +pk = 3E31D5B9C4FAA343548D389DA16BA6D1EF1E9124B45B7967EB704ECA8F92757AF6073766C60147D3E80197785B01222E937C6D5EF0180159E8EEFD36A81F83687BA289AD1D8F6B670FA6769FCAD4885D63B18B872DA9D237A7B3940D04167ABB9607A43C5857C50DA3CA41878C00158C037DF87BD887FE08B0D680CE17E3A155FEE2CA9C7C61E98C55DF845D7BFACEC8CA2C7D70A369F2F057CCD5E1C74FC3C968E49E260218E036B49BEE4E5B31A2B584695D24064EAEF02EB715E33DE8A47431AAAB5164D2962F7E019EB40CFCFFC34D4FE16EBF5B786A28EA67014C6B7B5DD887147DE93E26D968596B4D641BEF8510630F5270A06A1469DEBD3F97C2E2D7C41B57364E7A108B78EA7CF3C0F7D6B9FD93007B5799737117CAD561FA9715FB204C9048374CCE2149E09401CE7E9DCA4F083AEE4B0929EFC6844EA7151322154D30B974AE70FDF61701 +sk = 47550E9EDACB6DDCE3D9AB81F6B61080A9565C4770C1E638BEBFDAB6C9724C0371A22DF2F3EED0FFDACFE8003E31D5B9C4FAA343548D389DA16BA6D1EF1E9124B45B7967EB704ECA8F92757AF6073766C60147D3E80197785B01222E937C6D5EF0180159E8EEFD36A81F83687BA289AD1D8F6B670FA6769FCAD4885D63B18B872DA9D237A7B3940D04167ABB9607A43C5857C50DA3CA41878C00158C037DF87BD887FE08B0D680CE17E3A155FEE2CA9C7C61E98C55DF845D7BFACEC8CA2C7D70A369F2F057CCD5E1C74FC3C968E49E260218E036B49BEE4E5B31A2B584695D24064EAEF02EB715E33DE8A47431AAAB5164D2962F7E019EB40CFCFFC34D4FE16EBF5B786A28EA67014C6B7B5DD887147DE93E26D968596B4D641BEF8510630F5270A06A1469DEBD3F97C2E2D7C41B57364E7A108B78EA7CF3C0F7D6B9FD93007B5799737117CAD561FA9715FB204C9048374CCE2149E09401CE7E9DCA4F083AEE4B0929EFC6844EA7151322154D30B974AE70FDF61701 +ct = D650509DDE7464111B4EA141829D2AE11C99A6A6048D81F8E4B84FD3CF0C3A3CE1E517C383ED69872692629F221D2D7162CD48833E9501EC94E5FE08640D787EB57282DA5DA19A1AACF4E5F6404DB460B6CB6D080C1FAA0136FED6148677CB751CFBA76ACA6767283BF355D1EE00EF753300EACA94B208A403DB0A489E8FF98BB37245E70D51C1174DDC3CA05B1F8BF668E05BAF40C65AE7091E913DF829B59746559C60003709342F980D8CE03AB73468895480E419361B2703096ABBAE078BA806FD49961AF166D861E25A479C13BC91C94D2DF4C40CCD796B07018E876D89189D36FC852816D88ACD9818299AD1BF4B93214501951D759073173B99377241D2F026D90B71BDD749B429693CFF9AA4BD9A00F994B2155D0568C905C605DAD83B193BAC6E9845DF9ED18FE095329CAD5D874AB9BA3B0ADCD2C52F2E61D10F53D848E48CAC018766FD01C9EE56FFDF8B3A224FFFDB433440D874 +ss = 8FA20B8DCB491DE5FADF49328709045D + +count = 42 +seed = 44A6774B2CAC02DFF210FF861A090561A453DB311F47B6FEDB81811872D5D9489F5FC4103010139AE53FCAED209DC9BE +pk = F477C54C20925686C615D5AB3F02428BC4B70F39DAD2C2F11CD2860DC1D01BFEA151EF4C188984AB38FC3E2DA5F8FE3A335A3262F19D018CB15E9E2AF72D41D06897B3779A8583177D9EF3269F2C834B837E42FF81955DA7164F5B638828065E48B96FC85F92965337E8BD992D02930D37015A26C2107810FB12EFC8F28AA086207DEDF597C18835CCA2064274988189714A9979598AFF01CA0CF824D0148FA804478BAE00FEE5E5DFF9311703D37537936E1CC8DA59243DD3592FF877827F6CEB695693DD2E20A92A1A2B6D9E01BA9373ED8907B121DB11DCF49900153A06215D70E25D409559CC36562DBA68D97997FB101A02952BFBF27EF9EAA5C080C8FA617B69D6CCD09CF1F2CEBE4892D2FC0BF63F00E9D949CE085AC7D7A63D318FC7B5132EC9A7AE1D953C036ED557728109628043E89807D8AE94F0BD9015C0FC1896785FF765DCA75EEC01 +sk = 610AFB64BE8CC1DF288CFB016EE2F44CDEDFD97038566534837AE3FF6C465992390EF1D33871468E46101B01F477C54C20925686C615D5AB3F02428BC4B70F39DAD2C2F11CD2860DC1D01BFEA151EF4C188984AB38FC3E2DA5F8FE3A335A3262F19D018CB15E9E2AF72D41D06897B3779A8583177D9EF3269F2C834B837E42FF81955DA7164F5B638828065E48B96FC85F92965337E8BD992D02930D37015A26C2107810FB12EFC8F28AA086207DEDF597C18835CCA2064274988189714A9979598AFF01CA0CF824D0148FA804478BAE00FEE5E5DFF9311703D37537936E1CC8DA59243DD3592FF877827F6CEB695693DD2E20A92A1A2B6D9E01BA9373ED8907B121DB11DCF49900153A06215D70E25D409559CC36562DBA68D97997FB101A02952BFBF27EF9EAA5C080C8FA617B69D6CCD09CF1F2CEBE4892D2FC0BF63F00E9D949CE085AC7D7A63D318FC7B5132EC9A7AE1D953C036ED557728109628043E89807D8AE94F0BD9015C0FC1896785FF765DCA75EEC01 +ct = A9DC17012D96FB5A6C1532FAA8A61C3B85FFD45928E06CF1E020BBB15B37CDA74346408C54C14C08119827F6B21F3B8B2615C7A076F90090F484393B27BE9FA7E4443AA1233109A9E99D625DA9A44BA5EC706782C5597F2ECDA421D047CD8656470251154DA75008645B1B43B300E885C99264C5B4E695B2E7E34815CFEF4E01FE19BB010DA6E4C5EEC84F5A246C08A90141CA2C765622F57C125F8652D1730E30D2503B01CBAE0487ADAE6ED1E3F2110AA0F418C673952FE9F9A35547D9B970B506A571FE48F43D9563E2D5F441825934B5C5C7F0531D082B84D9015ADA11ADF397B2CD39356929CA5DCD3C380AAF76CA7463EDB9FDC12C7F10838C2428944BC0D95EDD10A6FD4C5819883C0EF6CAF0A84701B493C767C9EB9C9C8F03A6241C20123A3107DFDC305548F2C58B6C8AA9BF5D49257EE25042F0E214316F9AD0E14E6D326A3A3995B86200700075F95FCBE42E06D48D21DC51837F +ss = C42E0777D7ABAC1417C39BF318CF4F5A + +count = 43 +seed = 49E1855588B6235DF2A400C4A70AEDF8AB17B6E5E2891AA745F132FA2E7AB0C8117C1DF37C39F5D57624EB77C2B4A091 +pk = 84D7A1EA546985E802AA24458B19537402AE8C43332C8629EDB71C1A129659C593CEE32F282A35E423F15362DFCAAB4FDD695395AD1E00C00D169419B0F8BF1C6F9E46574912790A86B94BBD0ED436865CD55521B3ECA87CEA7594ACC5485DA814C0ACEE9307BBAB6FDA285DE40069F81A1369416A5CED9EFCD011543ED3274AC633F22C31DC1A4093CA76954D8172A40E0D388C8595843F98B8B6CFD916E3A2706616FB013ADC80396980A108B680E645BC8424A821C1D287639F196F001A11959A0C148F4BCA151A039FEB2D47DDC90C0839D079B1F0137FB8DD00872C73089A4EEDA971548E59F59ED959C443478185321E03B307120F2483C64C4EE1BE5427C353840F6C518CF8DC5DDE280A9AC485540017BA69AE6DF708043DDD11D7605A4E24A2C208C1D6E867BB0C25CAACCB0FEBE2D7D3E3881145CD089EC76B0957C63F08E63CDA04DE4A01 +sk = E1953800ACAA85AC02A906C72CB8E8D7AF2ED0F29F56400BB087C5C7CFC24CCD1756634FDD14A884C51DF90184D7A1EA546985E802AA24458B19537402AE8C43332C8629EDB71C1A129659C593CEE32F282A35E423F15362DFCAAB4FDD695395AD1E00C00D169419B0F8BF1C6F9E46574912790A86B94BBD0ED436865CD55521B3ECA87CEA7594ACC5485DA814C0ACEE9307BBAB6FDA285DE40069F81A1369416A5CED9EFCD011543ED3274AC633F22C31DC1A4093CA76954D8172A40E0D388C8595843F98B8B6CFD916E3A2706616FB013ADC80396980A108B680E645BC8424A821C1D287639F196F001A11959A0C148F4BCA151A039FEB2D47DDC90C0839D079B1F0137FB8DD00872C73089A4EEDA971548E59F59ED959C443478185321E03B307120F2483C64C4EE1BE5427C353840F6C518CF8DC5DDE280A9AC485540017BA69AE6DF708043DDD11D7605A4E24A2C208C1D6E867BB0C25CAACCB0FEBE2D7D3E3881145CD089EC76B0957C63F08E63CDA04DE4A01 +ct = 1BC8FE87FCE9963FCB70065B9039DA084F17CEDA8EF3793E1D7CFB64249EBE391D00C5372CBA206D6A9A4E170056E010A1C2EAF10C1A0188186E4586A3A0425F02CA497F8082FF39E732E36396D72C2BAF7D1600AC642251D0E4B32E604214675D6E00E8499693982C789003B7008899F0C38BB17139E7AB373E3E2E4060D52A4252ACDB7C36CA4497C5B9E4146F3C617CD35F4F831069B8585D3589EEA6E8AC50B0B92000D20613E79CFB402D1357E3BE6F588C5DD76834E152DAE7E6124E4BDCC85B93A499B26DDEFFAA8CD5CA15C5A70FD58DDB318E81FC026101878A361EFA8D395F5D1340E78FE675DADFCB58BD5E0DE320F118545686FE6A94089D7D811DC0C9940F68D2682192A069FCB427A3C4070125C3883CA5B298633EC03A5E05A387DEA577E9F50154DC5BB4D1225EDA565BC975DFF2B2DBEE75DBF06876FCC4947427E5353FC003EA01442743FB3385F49DDFC51F057E1A8A18 +ss = 801A1A7CA92866C67832D4E33D5C771B + +count = 44 +seed = DF0E41D2F6F86C1F79D31FD5878E7AB434FC0AF3A0D5F47D2AB3FEF31A42BD949B0E3629DF9F575BEFBB62E829E51DAE +pk = 1AF9AE7F5D9836088652DCF7DE5B92A5C07DAAEBF77D8A5CCFB27D1097A92DE3EF714E99876B513840FBC08BBE9AE75C33A25D78346801052153FC316DF0D26972AEC8E8BEF3F159B30E8787B562CE0902672275DD1C5994A83E3D0B2C086D7C4827A7458CBE52539663815333024C6D6984D36F47FFCBC2B3B819D9B4897AFB21879AC36D21971B2DD548AFB0DF557094422258AEBA3E4EBE3873E67C6CA05E03A5EA10012D1422E446F7632278FF4E7191FE22FB77CEE507C91E32969171CD4205B38BAA8BBE4FFDEE41CCA2392E4FEFC4AA5B4A9079822E45A3013E89DD87A8EBAA9FE2BC1FA1B9E4390D5A5549B78774E6EC21AECD5EB1E475E2C0810E8BABF4603D72C89D9429C956BAB82598E3220B00021F193E757551BB62941A47C8510F633629E0220CF4EF9D7617F5A50E44C914A9CCC5BA67688B2B7C7F5E6126993770662834DDAA3500 +sk = C719F9B2D16399B7326CE4ECA30DABEF8A7B00848AB1F261D351168973AD4E4DD3F28CBAFBDD282EF717D1011AF9AE7F5D9836088652DCF7DE5B92A5C07DAAEBF77D8A5CCFB27D1097A92DE3EF714E99876B513840FBC08BBE9AE75C33A25D78346801052153FC316DF0D26972AEC8E8BEF3F159B30E8787B562CE0902672275DD1C5994A83E3D0B2C086D7C4827A7458CBE52539663815333024C6D6984D36F47FFCBC2B3B819D9B4897AFB21879AC36D21971B2DD548AFB0DF557094422258AEBA3E4EBE3873E67C6CA05E03A5EA10012D1422E446F7632278FF4E7191FE22FB77CEE507C91E32969171CD4205B38BAA8BBE4FFDEE41CCA2392E4FEFC4AA5B4A9079822E45A3013E89DD87A8EBAA9FE2BC1FA1B9E4390D5A5549B78774E6EC21AECD5EB1E475E2C0810E8BABF4603D72C89D9429C956BAB82598E3220B00021F193E757551BB62941A47C8510F633629E0220CF4EF9D7617F5A50E44C914A9CCC5BA67688B2B7C7F5E6126993770662834DDAA3500 +ct = 2F76E5EB32E7476CBB33890AD997AA2A9DCAC8354E810D4E9BAC76EF28FF5E6B914DF4CFAF8E1A36FED7014FC3F7238FF1428B615A1D016EC2560EE809CA20204025E2E6F6ED7115A05545996D7B186FA2E83022075BD63FB800FA28A9762F02C17A8C89DE435236B742DC3D4701B5D654E2B09F9112D14E1922C8D579D68BDBC507C82422A770BF5AE64CDCB751A809A3804405E7984A68DF674847BE790985E3CF75A8002EF07B7732928F21FC87AB4E1FCED3BCF74B0982290511A60B5BE65E5FAC885426A8FB9550D6CAD225A8860DF034D8E3E088B63930650078854EEA7F6323F4C9F783F6F8D889769AF037AEAD6805BFC9DB1D408DBAD09680E99BD1E2B068968D0B934A2988453D1DB6AE1E124800246D8AB7C59A9F8C82D7567E316D2CD2D05D122042D9BFFF81E569A0AB5AA1EFACB0BE9851FB15511B9CAF745500E5A853F86940D40E01BF9B9F3E74418C343F2B9CA8E457C7D6 +ss = F8E403222BF0E2ADAF1F08C95D008ADA + +count = 45 +seed = D3C9EBBA6EB03CCB5C9B9D2C8D7F0CFBBF50841E24396CDDF0E56525B38918C2FBE6C34CC1B93F7BCD4F4D5777E1A488 +pk = 9BC769B4CD1637CC475A63DE751C41B30B71DE90A23301846EF3BE062DCA54C42EC189EFE6F5078E9EAEABBCFB3B182EA7108A82639D012EC1161215475CFEA257FC9F2625B40C34F4862E5077097D2D9263FE574C1236E07595A3BF8F40DB367D7C1753D39F98591AD363DA9501AE0EE69305F4E4076E6CABFD2EDBADBCD3D2D228C83C2A7BB0438DF57E9DF20A29FADF414F7803BFEB9E5566D797820B46A9E5FFB3AF00CABA26F15FC79C6E926D0309B95DA0DB28F0A00B6A9D25BBA050B24AE447896516543A215ABB6E056FBF0BF5AA9CF78B573AD94B90FD01671865145687EA8CAA6C695EAD2A250483F4F7375F22D253A54D02E07C2ECD84C3E2092D157512B00EBF797FE94A5ED0EEA0C55D8A000084BA5EFF506B09B6DFA30192F21A0D5332C52608B4F18BD7F89576D8E543AD55D316348E79FEA81734D1A00A9848A997207DD25055A000 +sk = E9ACBB774BE970206C3A738E243B420864E3C9BE202513B43165B8BE1F2DCE13088992F78B590D6DB2233A019BC769B4CD1637CC475A63DE751C41B30B71DE90A23301846EF3BE062DCA54C42EC189EFE6F5078E9EAEABBCFB3B182EA7108A82639D012EC1161215475CFEA257FC9F2625B40C34F4862E5077097D2D9263FE574C1236E07595A3BF8F40DB367D7C1753D39F98591AD363DA9501AE0EE69305F4E4076E6CABFD2EDBADBCD3D2D228C83C2A7BB0438DF57E9DF20A29FADF414F7803BFEB9E5566D797820B46A9E5FFB3AF00CABA26F15FC79C6E926D0309B95DA0DB28F0A00B6A9D25BBA050B24AE447896516543A215ABB6E056FBF0BF5AA9CF78B573AD94B90FD01671865145687EA8CAA6C695EAD2A250483F4F7375F22D253A54D02E07C2ECD84C3E2092D157512B00EBF797FE94A5ED0EEA0C55D8A000084BA5EFF506B09B6DFA30192F21A0D5332C52608B4F18BD7F89576D8E543AD55D316348E79FEA81734D1A00A9848A997207DD25055A000 +ct = DDC23AA5D837BBF6CFE201305B7A2CF7B84F83A9C1D7F5E935E9CCC006B0307FB97726983153D162511E93B6533B2E32A420C36A6F69005D543140F298B7B710D7F1FC6E94779E6D8C084C477C76C2406536B8A9ADC13E0DECD68A9658C804EB8EFD5EB6D14EEF5594462D331801711A94E2FE441A0729BC18BAC6291A2C2D51B1AB178F1B5160BDF300DE2C026AEC8B9000A7C33565890A44CCCAD08AF2868B61ECDA0C01238A092E7850F1C5BEEC3BA88421E28F8EFA6F8F5295CD36F0B46E479765D534178B05D7C85B7D4E14E4BB712A190F02565FFD954C36018992071DA173FE5E831A4CC7EFFDCC7C3DD024EB4188EA8892471187E935492B53B6E54AADE035DCEA5069329B772D6CBDAFD52E44B6016898CFDC928F424091B39B2511083978FC27FB3992893EF1C5AEC269FF90AF976996BA403802ECF3196FB9CE394BC934908074E291340002135143A60387AC1F0A5B6F7D9D8A7E +ss = 35E3D14C2920FC09FF5D0E159609FAE4 + +count = 46 +seed = 6B3996E8BC6F52879F2B7BE012C44AD555707CB7E5FD8ABB3457A298336D6FDC9EB7853008FF13201D5969A315C7E493 +pk = 3855AEE68558398E50CF49B80C47635620A9615408A1DAAA44F71DAEC5628B1AAA48A867F13B4176561BEAD2977FDD349D4D3179EAEE00D1422CF125602802F4AB08102F9DF7C424AC1D882C4EB39C29B147C560CE9FD6260037F9900CB052E4536B3532775A7F5B5BA99BA03901EE24DA256BFEA66EB5CAB03763B933A29156E72B0B82CE014403F4CB65ED06027256182ED0435E855F1EEF5A8B40348E47628041252A00750BC000779CEFD5B19E94D25C7ACCFF0C49D74362837A97719A8B31E11EEEDCC33FDEEC0760DE1862AA999485FF8AF8178CBA394922026E447E6AC2BAE3D31069764C8E0B80A2C749D94954010A324C49D737113AD179E8AAB6CF24B42967EBA28776671D563E852837501CC80094C3CD5041D31AE72717C1B747CF3351F878F356E351DA56DB8AD154FEA375AA878F6298C60F4FF501FEB44095E0F1D1A6AD6C91948401 +sk = C1B3CBFFAD4B306F9AF0CDD302887648D7C02BF6EF9C5C44B7D40B9BF861995EC09DBA98446A8F7B5E6E65013855AEE68558398E50CF49B80C47635620A9615408A1DAAA44F71DAEC5628B1AAA48A867F13B4176561BEAD2977FDD349D4D3179EAEE00D1422CF125602802F4AB08102F9DF7C424AC1D882C4EB39C29B147C560CE9FD6260037F9900CB052E4536B3532775A7F5B5BA99BA03901EE24DA256BFEA66EB5CAB03763B933A29156E72B0B82CE014403F4CB65ED06027256182ED0435E855F1EEF5A8B40348E47628041252A00750BC000779CEFD5B19E94D25C7ACCFF0C49D74362837A97719A8B31E11EEEDCC33FDEEC0760DE1862AA999485FF8AF8178CBA394922026E447E6AC2BAE3D31069764C8E0B80A2C749D94954010A324C49D737113AD179E8AAB6CF24B42967EBA28776671D563E852837501CC80094C3CD5041D31AE72717C1B747CF3351F878F356E351DA56DB8AD154FEA375AA878F6298C60F4FF501FEB44095E0F1D1A6AD6C91948401 +ct = C06089A9ABE630E39E6DCCFF03B9DCECFD69115739E62E64D186B1DB5F9F8E3DE5B026E4138CA882DE699AADD624E420D903EB6A120B003EA8028ADE6E15E68655597ECD81D8E0D7EC083C1B4FC520E70979DED438D25314CBCA659C1DE7105E98C35B1626064F6AC230CB77DE011A16D911A5929997DF29DF864BDE00B104334973FF05158371E37F795D4D5833D9CB9796516C092AC4EFC18074BA184415C79181E8E500F65C3380A3676B7685AAA50EBD536B3933FAB14B17EF85BFEEE90409B5563831068F0EE30864DBE8849C8D74583EAA142EB7E7AD39E70087462E7BD3D6127C2D57A5F5A2D3A73709D77C84A6B589A1DD2C128A2F6BC053FB383ECC695C101629D01D65967F103BBA75FF710D4E0114C3584E437750D652C54DE7CDC50193507136DFA2A7B88C09564FCD5635D3DE2E8D7BC12B2F814A829E29FA7F15D055A0A72A93101800E3F9AC7D3DB8E1F5C18953D09699492B +ss = 63FE00582274725260514057BF36BFB3 + +count = 47 +seed = 730B65ECE22DE27D573CE3AEA7CB021C415DF210D228808D91D4F380070FFCB0778B683C71D4853DEB569C822765F2A3 +pk = EA7F957F20FD5C7000B0F1F401355BF496C1644CE31F5640FAB4E5948603FA389D967E982A2F6367C777B5346D658969D6B6487CDCCD0087374CE621387C9316165D241E611C94573CB275BBE7F3EA03439273B5761702142F360E8FB87FDA01663127299123AEBB0017BA9420004D2516787A5CC733DE612F97B4F4B63FDDF898D2594457056B6D676D470510ADB8C09821D1CF6433B3FD1473CE158595D7D22BCB4C3C002454C724EAD9B3AC44C2121518757CE786778FE4F955A99EFDA20B531FD76684420288C8E74AA784F3C6D58A076095BA3A21193B1803003DF45FACFAA76D8F2C345A9A58E14B45B9BAF5260257A6BF6B20751676F604F0E75E6A69AC88557B9EB6B238C6402EDA6C44BC79D3CC006A2D6874D92531681EF09856096FF45FD89DA50E429973C4C74B6DDC8C436EB0B6E2A1725DBF26E357F3178E2D353BA245190A3461C700 +sk = FF7495B8575B5A98E4FD21FB4C3E58CBCD336920AAC5667CD62074B3D34C7C6EC0DDBCA8333F73AE42194700EA7F957F20FD5C7000B0F1F401355BF496C1644CE31F5640FAB4E5948603FA389D967E982A2F6367C777B5346D658969D6B6487CDCCD0087374CE621387C9316165D241E611C94573CB275BBE7F3EA03439273B5761702142F360E8FB87FDA01663127299123AEBB0017BA9420004D2516787A5CC733DE612F97B4F4B63FDDF898D2594457056B6D676D470510ADB8C09821D1CF6433B3FD1473CE158595D7D22BCB4C3C002454C724EAD9B3AC44C2121518757CE786778FE4F955A99EFDA20B531FD76684420288C8E74AA784F3C6D58A076095BA3A21193B1803003DF45FACFAA76D8F2C345A9A58E14B45B9BAF5260257A6BF6B20751676F604F0E75E6A69AC88557B9EB6B238C6402EDA6C44BC79D3CC006A2D6874D92531681EF09856096FF45FD89DA50E429973C4C74B6DDC8C436EB0B6E2A1725DBF26E357F3178E2D353BA245190A3461C700 +ct = 26457EAE4B95CA30CD09FCBA508DF98CE0E6FFEA62384B8EA08C0D7CB6D955560ECA8B6B66EBB98323A053B36197772CC29BD9E83656010AA821C165CB6B91E84C123D8B48233C45F64560327E3BCAA19CB17720220001E115D53AF3B659DBB3D27119DF32645FA2CBBE9694E00151CA76371C628F3D4530C6B2809FC7944EFD2F25E64F38A3381CD548D8731AB95A30D76EE9B8DCBDF74CA590B08C92921770C88487AB0032050C975F81DD857D3EB16744A97AC4C3F42BF12343FC7A2CE753AFBFA2F7FC4C136C9C1373E71FD76316D4F42BAF5EABC82DBD151B00B5C238B51B6ED6675DD9F4E80BAA7DC99030830F4ABB892774E766CBE0A4B480B1090C880192C7A71E75A5134D767E2847CCE03579CC00DED00B0E9A385260A0459629EA6AB8CDA972ED0BD697FCA88233A2D67404123B1C22796941A1B29E253EFBF49F0BFE4C5F59D13DB2A301B3645995DE74A846A14A5262D60949F3 +ss = 9A176F2E3F1B00AC7385E9CE14BD60A6 + +count = 48 +seed = 5522A5A891A9A9B5514F4556AFD8DF40B9CEC63A01492F0CB8A1DB073A285A963E4A9FF2376C88662F7D8D241F8ACF17 +pk = 8F8D1BA886220CC3AC2EE16698A510D95BB9B1E9CE880FC9574F4CA4359951E45AC9178E60DA2F38D64D19E9209B8261F7CCB74371EA01E420CEDFFCEC2A3A140F029D7A9AE33BE1594661C0667D0583141DF26C19FEE2933C8C56A2E7A2D9153A3C48EF0596977AD6AB0931F000A5ECC743B390253F8BA48A2E62FB4D4561E226F659E145BCC22E34FA66A6E4C66831DF931CF2AC756B682A55CACABF5A0FF27067F4730178E62498DE47AAB31531B35D552178F04B4E98CA7A6F236E58060F18121B2FD3A7AA180717788220C74C8986AA8B0AF7C4357687A20C01A179F3778C715BBC0D2BB89FC3C04BC8C1CF072B245B73CEF3821E48A744E118F5D3226E6F0F976B6A06D70678113904349E5B66043E01621C8D8F6C3E72222B2927F75CB14196DF99736978705E9248138DEF65A7351615199784B700E453858A7256AC52F5A7065126C3173601 +sk = BDC3FBA1C32751139FC45BACFFB3EA97209C6B9A077825C43E36AA2E13D7B93FE5364DCEC0D2F23E705E3B008F8D1BA886220CC3AC2EE16698A510D95BB9B1E9CE880FC9574F4CA4359951E45AC9178E60DA2F38D64D19E9209B8261F7CCB74371EA01E420CEDFFCEC2A3A140F029D7A9AE33BE1594661C0667D0583141DF26C19FEE2933C8C56A2E7A2D9153A3C48EF0596977AD6AB0931F000A5ECC743B390253F8BA48A2E62FB4D4561E226F659E145BCC22E34FA66A6E4C66831DF931CF2AC756B682A55CACABF5A0FF27067F4730178E62498DE47AAB31531B35D552178F04B4E98CA7A6F236E58060F18121B2FD3A7AA180717788220C74C8986AA8B0AF7C4357687A20C01A179F3778C715BBC0D2BB89FC3C04BC8C1CF072B245B73CEF3821E48A744E118F5D3226E6F0F976B6A06D70678113904349E5B66043E01621C8D8F6C3E72222B2927F75CB14196DF99736978705E9248138DEF65A7351615199784B700E453858A7256AC52F5A7065126C3173601 +ct = 878A0E555EE2243BEE1CDA2BD6DDCEAA0CE5269DF7C2B71C78DE51194FFF8F613D7065D790C38F5A30744A597616718BD4509FF988390143B08C52B658E64E81D267128E56605607A3A6CC903B265FF6B8F4A141B5E2BACC453C5178D992CFA662DF049BFDC13425B08F624E7900A32599CDB0B7899AC104D7A6BFD9866407C2DC477497D381357A7A5B1E2CA3BEE48B6CE31764757BC91BA90F678D0FD4456985383628004F0B1C929384E1CFF8E2B838472C284AD23A631D8B189AA048A58D1F9327B5B139B60047E2C9FCD3F4AFC1ADA2EE88CBAE8F1F6A341C01D3FCA36C8FFEF006BAB338363745230AB09EF0C2EADA67DF23F08C67D082349D12864ABFEFD0677F8CD253B7C4B5985AE13D89FB762001F54B4A50021FA3C7AACA6DAD85D540EDC2127CA638ED8C2B52DD0F607895C347B27990A2EA5E2F565F2EE45B977C40E8266ADE4A4B250068964C321EE0E31973B6F9906D1C1236 +ss = 7388DE674871722069D24664917D44B1 + +count = 49 +seed = 1853E72329353B3F89AE6A1B1EF700DA8ED3C10D19F9E61EE9252E28EBB0E15802EE43083A12A0B7527088832605E3AB +pk = F244A7FA24F6046396C3EF3B0DE1739DACF1801CA178DEBF5F20A3849942C1DE4BE218A44434B95CB07573984A466B5AE03564A78310016FB3DEAE453101ED20E832B441EB82B55268F0C584ED9707914E270F7FC9FCE597C63F65B6378550332D998E9C047E4021AAD922441E01B6283505788EEB23CA1E34044D76CB8278EF97997F78D0132CB1E522CB047C50B239F73E5E33EE354408209B5AFA7D0C86AEE02121DD014D12417972032548E3D3AE9032861A01174426B8661253D31680E59F8C8901471EE733669E7E2DFE36262F23E01B1ED4E73A86B5D2C80197C6F5859B8F6DCC50D4F8CEEAE3A913155EBAF952CC1AC150CD22A66A6E0ED2C0B292A04E620E8E7177133B7334AC89CA6B93290AE100266845387F657467A1C93AF638759EE43E6D780D9C485CBCB8B9995FFE771954F93B5B41B3E96F3A57EADF5F833B5E704C845C2EF26E01 +sk = 447F6076A627BBC5AD7773FBFEB14B4BDC2C66BC573F32EF57526D55DC22497E8C412552485CA51850F29800F244A7FA24F6046396C3EF3B0DE1739DACF1801CA178DEBF5F20A3849942C1DE4BE218A44434B95CB07573984A466B5AE03564A78310016FB3DEAE453101ED20E832B441EB82B55268F0C584ED9707914E270F7FC9FCE597C63F65B6378550332D998E9C047E4021AAD922441E01B6283505788EEB23CA1E34044D76CB8278EF97997F78D0132CB1E522CB047C50B239F73E5E33EE354408209B5AFA7D0C86AEE02121DD014D12417972032548E3D3AE9032861A01174426B8661253D31680E59F8C8901471EE733669E7E2DFE36262F23E01B1ED4E73A86B5D2C80197C6F5859B8F6DCC50D4F8CEEAE3A913155EBAF952CC1AC150CD22A66A6E0ED2C0B292A04E620E8E7177133B7334AC89CA6B93290AE100266845387F657467A1C93AF638759EE43E6D780D9C485CBCB8B9995FFE771954F93B5B41B3E96F3A57EADF5F833B5E704C845C2EF26E01 +ct = B5FC58AB9096E102E2D28E52B8D2FA2BD5C01C2C6E3BC8FFC34FC49AC77E2EC3CF8312D537D6E93B1853B012872CD64E68A7856D2C570089296B09E609162B52D7FCC3FDFF1F4ABD89D4AA29E72623DD661175BDEB2E1232EDDC5D56D0F3D85FDB888D6A47E337819E31AEA1DC01B44BCB2982C0F4FD367041A48F32F794D5180A7B85940C420424C4BD7075FB60708A006D914311DFB496E6745EFB07AE5E0A5B524EDD00C7BB4DCD4CE64C2333EAF1A69D0FB38BC9802AEF65AE90337F9B59DD881D3CB9615DABC8B6BD7B33AD887D70E1ACC0B8D17334FAD63C00F300B94853EC93E4350D73EE2D26361F8813446BD9C98567EE0CFBB7CBE4336E9C8AC43260F71749D86F54494FB5051FB9BA727917E901C30DA11BFA89D651F9C2266C5E93C8DED379CE219F72BDA5C1A372CE01AFAE819A63D955E79251A0368A03923C587DF047C46C7EE7E801E417AEA7630FA259A363A29014AA543A +ss = 82BE0F91FFED9DF2F66E264621DA7121 + +count = 50 +seed = 027C3D5847ED4470931141104F25B19AE76117CBB64B224EE424FFB782E9A0E988839E0BDED0DF666FE8E5FCBB5DBC09 +pk = 4F780D5C1047ECF584DD204B2CC68102DD0FE9D5FAED786302D8DD7DF41617F9BDFFB120EDE1BCB1E653BEAA873996AE53FC5EB07B2F01FF0C6E0F885525E214E8A6E9F92A8D69E10FF9660E5FA5DF6FE843BE5DA347B44ABA8B14535BF8380C1D1B692AA345F9E5E79AA1E3DA01410F49FBD5B13128156D84F801E5521C91903FA14740D393149BE1A94221EB95F10AF676CBEA84C6DA1E94B08547FACF44ED219200BA01E52161E21BD716AB760DF8C54A7A9838326C1811340ED2E1ADB1F33707CCFAF252E0211C6882C0F74C4DC275385430BA0845446E3533022972C815F0D257E308E7745F5A2FA40F3BBAD0850A6BD0AE2C7D2EE4174827E7796015EB8214ABE8CC102E381B599C4330D26BCAB0E2000E27A842342E7CAB920BCEBE5C69E5F1A0792B43A19006E20B45DB8D1B3133928CF2703680B7956EC2930D1CA626B7393C7EC9450E4600 +sk = 2D5DF64D62CB07FE630310BB801C658D90CB357285DAFC246676B8CA88987EBE61947D3FFEFF00BFFBC37F014F780D5C1047ECF584DD204B2CC68102DD0FE9D5FAED786302D8DD7DF41617F9BDFFB120EDE1BCB1E653BEAA873996AE53FC5EB07B2F01FF0C6E0F885525E214E8A6E9F92A8D69E10FF9660E5FA5DF6FE843BE5DA347B44ABA8B14535BF8380C1D1B692AA345F9E5E79AA1E3DA01410F49FBD5B13128156D84F801E5521C91903FA14740D393149BE1A94221EB95F10AF676CBEA84C6DA1E94B08547FACF44ED219200BA01E52161E21BD716AB760DF8C54A7A9838326C1811340ED2E1ADB1F33707CCFAF252E0211C6882C0F74C4DC275385430BA0845446E3533022972C815F0D257E308E7745F5A2FA40F3BBAD0850A6BD0AE2C7D2EE4174827E7796015EB8214ABE8CC102E381B599C4330D26BCAB0E2000E27A842342E7CAB920BCEBE5C69E5F1A0792B43A19006E20B45DB8D1B3133928CF2703680B7956EC2930D1CA626B7393C7EC9450E4600 +ct = F548B40FD2C1EC3E8BFD0A62B27016E93BC56A588F4DEFED3CE0D90B43EEB098391369587286E7CFC4A1926E9D9CBBB1162DB9416F04018DF7076B3A2EFC440EA7DE93EE8C3FF5AEF157A68CC7DCC79D56872F6055C982DE9152263C94C4BD1E635AC20CD2AA344D1550439B1602C21351776DD3E4BD31AA96322197B34271004F31FA483E7EF0EF9D0F9C9ECC57A179541B9C00BC09F4840AAF148B2E98D3D763DCFEE200B0D7CFCFE68D38B274CFFC44A2297DBF084E2B74F7914BC41C7DB62ADA327481133BC7CB2E1CFA93966F0D2A20172F3576C70407DEBC002DAEF9065C775CE1D91277F2835DCAB79294BAF2BD6AA51C0724B50A388E0DD9F1A575C2AEA38C1706FBDEB785D3A3FDD9E487B370490182B3CD180E1E0B7F42705C5ADA72039136EA84ABB920C708F1720F7DEA928C179E9429F9BF79E7F951F0CA332D04667160265E269A1000B8C3CD96AA512D829EE245A27BCC653D +ss = 6D343ABF2D3FE4ED15E5B57E54EFCD94 + +count = 51 +seed = 450751D4401737459C6D93E6C5F2FBCC4A3AF7CD7250CCF404BBB817A67BAB7B4C9D0EF4570BFE25CF919DA331C31D88 +pk = 2CD1C8A305F9501C0604C394B9963F61FC0F78FFDEFC2EB81369B124A5CA4AC5D6BEA02FB7BF4F07924234F9F385F3CFFFBFD6F0A82002AFA5FE622B6FB7312620502F004A8D7E7EA56D3DCFC0D3D99E19FF6ECC021673079D2472C33586A0B7D5937B7E29E6A2C7E79BBC1E7001C3CC35B76571C4D83BDBDD799256DDB2E17902DFD5E7EC0FDC821417D0DE7D0C93D26F4939D23135D3C29ED81DA9F928A553AD5F29D000B4A4A12BEE57602205540C4892FFB14012FEDE6ADC42B7FFC3AF0AA0E9D8A9E879E6AB8883C8157A5A8FE82EAF33527F871693FA29E201E081A3336718AB915CFC73ECFF7D73B00F3B631949DFE96B95A96AF9EEE8142F82DDFB66C86C1C012B11CE5E0E01CF4AF60E61B4CF7E0032982D766A5707D9D2D5C0CAC23D954C8446475DA29111C52FE6A9E13DD82F6160AADD4CE1AEB0A4804A3EB66666B179BC056BA249A701 +sk = 25056D1B8113BB362DD979D98643D7A79399C9B80D3F4839CB33CA0C0DC8C1577E4CEA5B8088492E452ECB002CD1C8A305F9501C0604C394B9963F61FC0F78FFDEFC2EB81369B124A5CA4AC5D6BEA02FB7BF4F07924234F9F385F3CFFFBFD6F0A82002AFA5FE622B6FB7312620502F004A8D7E7EA56D3DCFC0D3D99E19FF6ECC021673079D2472C33586A0B7D5937B7E29E6A2C7E79BBC1E7001C3CC35B76571C4D83BDBDD799256DDB2E17902DFD5E7EC0FDC821417D0DE7D0C93D26F4939D23135D3C29ED81DA9F928A553AD5F29D000B4A4A12BEE57602205540C4892FFB14012FEDE6ADC42B7FFC3AF0AA0E9D8A9E879E6AB8883C8157A5A8FE82EAF33527F871693FA29E201E081A3336718AB915CFC73ECFF7D73B00F3B631949DFE96B95A96AF9EEE8142F82DDFB66C86C1C012B11CE5E0E01CF4AF60E61B4CF7E0032982D766A5707D9D2D5C0CAC23D954C8446475DA29111C52FE6A9E13DD82F6160AADD4CE1AEB0A4804A3EB66666B179BC056BA249A701 +ct = E85E324EEBCE9BF2F204EDBADFCFF08FE598C6A66FE2861D88581F4374F3B30873DEAD8E63A2F4744C572A93CC8F8E1D02AF0CF690D600BDDFBD945A9CE99547A5ECB8884EBCAA85E56EACBE8FE3030F45E242B030FA301C08D054B2DEC4F8359F82F1F9CE73423587AEB43F3E01F14D62C6987D489C4D0994216CC83B6A26921CA1129DF61346A35B22A0E729CB766BF5216303E4CA189C477AC74C1698866C91F268BE010772A51B856405D105959F3AD8B48E7118758AA9AF90BF8CBA40ABFB581D9880CEFDBA851C690568DE7D4B2441591BA2B89B19AE30AC010BB2A2BF203380B15C7B42F72413CBC7835C1401530685E4EB8BD5BAEFC67B6F0AB2154F76362340F267A228E3AA7C714583CDD45131013B7CA4583B428F7716B8C6E796FF806FDA50112208F5D2786FC3A09258BA5A2532FA1B3A420FA3B505824A6EFCB768524A63AB055EA1004F92DDC352EDF886326216EF59206323 +ss = A1C30FF86FDE868B5D09FBADC336D4DC + +count = 52 +seed = 5DE720F2D152BF4E1F96A61E7AE5F1BED6B8548E32638C2CCEC9F43B87D1BB43DFCF334F0582984D27E440D519AB662F +pk = 380B70236FABDF82BDBC9BE250DCD716A1DEF6D53310EDCDFEB262943E2423FE42DDE0E6FF179EB9948323A9574AC0D2F3597FCD584E00AD39DC89E0A590ADFB6DA42D7FF54F4E07478D4F86A9987E95FCC26145544FB8ACC0D0B3338A3BC0D7EEE2715BA01D5FB25C209C30E9009FBB8B132CFC249A491B042A7A18AC3EC1E58F82164CB0B1D762598EDFE3E769F68317D5409E21F312D91F6A9091385F74D0118712B60098105DE309BAB85BD40A2788EC6A88A3D3A18E961176E8068F91243FE5C060B0346A7212182F4C5925DED2F1EF2212EC3AA04F46FFC901F01F9B2B62C514831D9CD8F9CCC49648B114772D1BF43D390EBC097A1FFEA3CEFB48621D3C8C03C6E3516EB99BB7034E7A526BA3757F00158C0AE3E08733E1463DA1219228E3DEB33E486209CF48D8035B2048FFB4776A8A98CEE549A89EA8B318E47315F4AD5E8580429AF6A501 +sk = E4D34E12982AEEB1D62FD488D9B9E2856F1336F0D4E622E3E950AD12176C29F0880458774FCCAD78D080F101380B70236FABDF82BDBC9BE250DCD716A1DEF6D53310EDCDFEB262943E2423FE42DDE0E6FF179EB9948323A9574AC0D2F3597FCD584E00AD39DC89E0A590ADFB6DA42D7FF54F4E07478D4F86A9987E95FCC26145544FB8ACC0D0B3338A3BC0D7EEE2715BA01D5FB25C209C30E9009FBB8B132CFC249A491B042A7A18AC3EC1E58F82164CB0B1D762598EDFE3E769F68317D5409E21F312D91F6A9091385F74D0118712B60098105DE309BAB85BD40A2788EC6A88A3D3A18E961176E8068F91243FE5C060B0346A7212182F4C5925DED2F1EF2212EC3AA04F46FFC901F01F9B2B62C514831D9CD8F9CCC49648B114772D1BF43D390EBC097A1FFEA3CEFB48621D3C8C03C6E3516EB99BB7034E7A526BA3757F00158C0AE3E08733E1463DA1219228E3DEB33E486209CF48D8035B2048FFB4776A8A98CEE549A89EA8B318E47315F4AD5E8580429AF6A501 +ct = 9A1733FC5D0AA11B4E294DEAF5B01567EA0EF9FA77BECB1DF566B06B3EA4B4E8A7273DB7EB99E1D9B11FDC4110A78B5843C61D4ED26E01B8180AD4E3637DF908B73EDD4F5F2F2E14CFB16FDFBF5004C36DE8AFBAA7EEBDFB4B02ABF5B39E927B5854A7ED7DC6E7854017226E19009C96CF54BB174F5AC38629E0C5865B0F7013E60C66C41E830CC1572F563C27734C3494488405544C94F68DB14863EA98528B7ABE6E3F019CF8108265915C68359D0E403DDDA592F76C3B114BB5B3C8FAD5DC801E9622EE8A5D95C35EB0B7DBFB5F2645C0BA027019B7DBBC0E4101533F462812A12ECBC1E8BDE6E358E16510ADEAA22F4FA4A332DDE5D0FEF3937D946D5BFD34011B1C6D2C7327DA4533BA02480370D3690198C8EE9736410AA5D74A85D1D19DFF276C01420418C50537A647CD589E40DB27695A49F7E8A56EE4F440F9E7184F1FB84CD76D5CA4B300F979FD4BD304EBD2B068FD18B7EE3F91 +ss = EEC1AEF4A49E035594CF00B7C02F9019 + +count = 53 +seed = D71729DCBB27D7CB39E9E905025D3E55C8602EFBCC483C9B866EBF82326157833169243C14550AD728BD1470F39C642E +pk = 737261D6870E16D9090AF3C4BFE788C0B31975F27AE90F44FBCBC8903CD79FD2327FDD89DFD4E1EA6DF35641563096FAECD0CD4ABE18014A0D070A5393BBE654585E5A932891DA67ABA32F8D80DF166E64F95072B751FABE434F38C62D7DAF8F7A50D03C6C09E9ACD9EDAAD7B9016072EA9BCD673D3E1B365CA17A2F17D6434D96EF04FACBB4D835B1974D4664DD5813621E895F3C01988D06B371932840C105E819D38E00C634BA9772B227A3B17D104744A4D3F2E0E4923A65FD97133BC854F4815021769E4122824CFECA04D20B1F122DDD175EBE095C3DA94E00B41D9B0B73D49FDB1DF811FD013C5DC69B66E291100794381D04EB4EC9588ED23C68DE7165EBA479E831C34EAB7EE12C4BE2FC9C07C200229C9B3479F3265BF2B45C86DD37A0F7107EB01BB034D2F65A8E996DA3A415D7FBC6E420D1B253FB25B827148D4D4A3278107BE77D3101 +sk = CD6A99396EB3539CA663A51E42063A3A6E29681BA52735192A80FA5D709F1AF1417DEA2C3235668327427600737261D6870E16D9090AF3C4BFE788C0B31975F27AE90F44FBCBC8903CD79FD2327FDD89DFD4E1EA6DF35641563096FAECD0CD4ABE18014A0D070A5393BBE654585E5A932891DA67ABA32F8D80DF166E64F95072B751FABE434F38C62D7DAF8F7A50D03C6C09E9ACD9EDAAD7B9016072EA9BCD673D3E1B365CA17A2F17D6434D96EF04FACBB4D835B1974D4664DD5813621E895F3C01988D06B371932840C105E819D38E00C634BA9772B227A3B17D104744A4D3F2E0E4923A65FD97133BC854F4815021769E4122824CFECA04D20B1F122DDD175EBE095C3DA94E00B41D9B0B73D49FDB1DF811FD013C5DC69B66E291100794381D04EB4EC9588ED23C68DE7165EBA479E831C34EAB7EE12C4BE2FC9C07C200229C9B3479F3265BF2B45C86DD37A0F7107EB01BB034D2F65A8E996DA3A415D7FBC6E420D1B253FB25B827148D4D4A3278107BE77D3101 +ct = 4D0CA2C37A3B14E09C0970DAA3CC5C13B486C4993AC910D2E72260D2382CC0D50603648B715D31CF7081CF709F76F456BF031FAFE27301CDEA5086C041DC07F5B582B71123A85C5C6D461C027C8772E6D4B0D9F2AACA2EAFD46702145AAD45895A160E11BA17B97538DC0668EC00CF5116041498764E937498EC2D2E0854C0DF508570FCCB74E9C659CCE5534383341EAFC0D0620A137D08519E38993660AFBB6C1E73620153DE56C904BE16E6753A552394A49EF9925667888DAEF0FA8BDB604382B03991C02BEC4861A37E711BE96E926A4AEFA5F5568AE2495501FD96148155C2377B16CACC5A26EE3836E6383C15A1C2D63BE77C4A99A36F62AEE32D10C22B7A569E654DD72E8F1444DF45A2B00AA346009153B38CB839CB211F8F3E5D5D348E0D43FCC66267F170432F5D3BF4879440C682DAA27E476F254795F06870EEB8C54A0ED96C7FAC34005D837019AB202BBE4609D72644445F88 +ss = 0BF8ED57229D0B958D41DC39CA6C6F94 + +count = 54 +seed = A7C2C8EDB3601396BEB2DF0657EC82FD5780A2723581A9E03DEE1CDB018440439BB1142CAB0487C5D136E9AF46338AB7 +pk = C51FAF1A4F4EB85E1A508A4336D492BD270A710C0E38343D0383ACEA2137A54D189C4BDF485F857AD58E15A40C7DE89DA8DAB22073B500D684BC760EFF8A3B7F44E200136DDFB82CE6D182D406A71ECA2FAA1799559C898465326977C83722F06FA6AE8974A18FB1C6EDFA133202DDE3DAFB931137F0C263C5E937F054C725B96F97B6F847CAAE501CBACC0536D1B372F3517ED9123D99061E3073019B2B66CCD6B15F480131BF3DE062F1DF0D2A6505BB1C30D5C0FDF2E66ABF83261C2E66F7D9FD19030FEA7C2655380EAEF87841A9F1479E18F07E8FA88063360111D8D730E5DE04520973CF5810B7FD02D9858C49039236B7AEA9ED490A12435EC24AD39CD01621CB50CA54E89B9C4AB00ACBBFCEA6ED007D14CC2B9BE43B59CEAD6D1B576AE686F13BC1482DE32043F07478961FD15E7C3FB17C373560BF2F9294541B7BE1C6DFE47C065B68FF01 +sk = 6C8C53ED6F65E6B2E324B84364E10DE4705B6EA889FB97589AD7990177A19ADB0CE37B4B5A51758E7D70E901C51FAF1A4F4EB85E1A508A4336D492BD270A710C0E38343D0383ACEA2137A54D189C4BDF485F857AD58E15A40C7DE89DA8DAB22073B500D684BC760EFF8A3B7F44E200136DDFB82CE6D182D406A71ECA2FAA1799559C898465326977C83722F06FA6AE8974A18FB1C6EDFA133202DDE3DAFB931137F0C263C5E937F054C725B96F97B6F847CAAE501CBACC0536D1B372F3517ED9123D99061E3073019B2B66CCD6B15F480131BF3DE062F1DF0D2A6505BB1C30D5C0FDF2E66ABF83261C2E66F7D9FD19030FEA7C2655380EAEF87841A9F1479E18F07E8FA88063360111D8D730E5DE04520973CF5810B7FD02D9858C49039236B7AEA9ED490A12435EC24AD39CD01621CB50CA54E89B9C4AB00ACBBFCEA6ED007D14CC2B9BE43B59CEAD6D1B576AE686F13BC1482DE32043F07478961FD15E7C3FB17C373560BF2F9294541B7BE1C6DFE47C065B68FF01 +ct = 32EB94DF91D635A31EAE1AE81C1319CD2E10B0AA35660BA45B99D982CBE07A2644FEC754C4FC59EEBED7E0D433FBE598F9E9C3B195B200788887150928874EF338D15A08F5F6C2ED66244A91463904374734F105389F3E9ADDC5330884A9E7465DAAD09A9CE2DD043FC2584A4900A9D434E262120FF948EA630359FF1A71483407879194C8D3B6A381CEBF5AFEFF661EC4B8C70CC9A22C99BF21474549F3538287318FE701FFF517B3F92D678AB79443386E4DA40256B861A43A0CB3D9EC5F2A4AD524373BE0D2DC495E49480234BCF67B01521E9FF2AD7771480E00C95705535765F7D4DFC9096927485FF15B5AB236A7755E51BED99B5F2A939367E444F68C0472AE8466049BCF5542D471CB332D36FC9E0049052B4EA30C9BC4133DA5DBE23A5616FBB1C0B98273C1C788C18D872A4452C094F8B15B94F9FB6204B24C5F6FA27FC2EB60A1B371B401EA3C58F71D6E68E43E0973F3552F9BB4 +ss = A3ABAE416B3EFD3FA907D5C21E9B8F51 + +count = 55 +seed = 467F6158CB86B724039FF18C47950AE5C49170163C910FC9A9B30141F86E9C06EBCEC91497BCD156D95758C9F0C6EF91 +pk = 98B2D052F7DCE2E26A25D28006AD08D1A9DA8E1FB331DA9E349AB449F6F0B1074A859AAB5D4B3241553180FF0C944E6B317190AF3A9100FD5063623C9B346C0F47D8D5FF62821E30E7B1D47095DFA078360D75B58F5042C198042DE71B87400708D4BFDB97B1A1CE57A0CD56EE00064C826AFA29AA726354C553F3DB19BDCCE701929E5EDEAF3F1F8D2214F917AF9AADD08C6DDC3CCBE6FA7B4EC45E9FC5FF3A946EF5B000753F2D2F8D043196AA802573104B5473CEC0E991E79472E00352954F82F202DECFD7ED39C80CDAFA88A952DDA57AA6C98DB30E61295F0006B8487B9575A04D5B699FD88C7AE8EC3D3D3F4F579C92427309243FCB2510D32900A25C452C857EABE89851FA2E634A15AF0761E42700A240DDE2201897B61DB0561632371BF5B14323B1DA1300A80AFC00E1A6B4853E7792695B4E9CAFF6F398BA01B5AB13C7DBABBC9379E800 +sk = 2107204CD995F1DF14314D5381F8C544036C7CF2D797F1DD5D2E23E80727FEAA67B5F019FE8AD45F1F7DB80198B2D052F7DCE2E26A25D28006AD08D1A9DA8E1FB331DA9E349AB449F6F0B1074A859AAB5D4B3241553180FF0C944E6B317190AF3A9100FD5063623C9B346C0F47D8D5FF62821E30E7B1D47095DFA078360D75B58F5042C198042DE71B87400708D4BFDB97B1A1CE57A0CD56EE00064C826AFA29AA726354C553F3DB19BDCCE701929E5EDEAF3F1F8D2214F917AF9AADD08C6DDC3CCBE6FA7B4EC45E9FC5FF3A946EF5B000753F2D2F8D043196AA802573104B5473CEC0E991E79472E00352954F82F202DECFD7ED39C80CDAFA88A952DDA57AA6C98DB30E61295F0006B8487B9575A04D5B699FD88C7AE8EC3D3D3F4F579C92427309243FCB2510D32900A25C452C857EABE89851FA2E634A15AF0761E42700A240DDE2201897B61DB0561632371BF5B14323B1DA1300A80AFC00E1A6B4853E7792695B4E9CAFF6F398BA01B5AB13C7DBABBC9379E800 +ct = E716FD738B7AA39239F4352BD27A7922F410A62AFC46AA4571080446FFF818E5EBB67E2FC799639FF75E7E8F1995E1369C683880224C002644DC773AF4F1F2B4A2C2A1A709BF2DA46C9813832DB3D404F09FD7CD3967ED3E9472F17556457C5E1B49446B3469990FF8E67B6F83001B547A5DAD929DE07DB1B25021F5E993A7E3B2AAA602380BDD8D6313EFBD26186AC880D9D842A9F0A0F91C8EE128A148CB566153D56400221C5ED3A4BAAC79F73ACEBC82C5647872140D38BAF4721D00BD0C10162848B68B83891C89A6832F1A5F3AC01483D47B9C0EA6A8DBED017672A221A099E9FC2A5C4C53E265001D2AEBEF0EAD8F44EA1671B6662E631F56CDA9062354C84DD9B49220262941AB9FA033C87C78CB004115282DC18AEA80E07A959104F19EA5972EBFA824E9D27D96ACF615B7747337E007F2BB32E634773E44D49FD1D0FE2D15BDF82E86F500FEF58818E5BDA791C1C85FFB43677F10 +ss = 66A0B0B4DF621E5AA3B0D21CDD7D9164 + +count = 56 +seed = 687C02DE1041ABAC7B2C1E6EC2A7C3375552ED5EDB10E3A8139C24CC76BDA44D719D8121A81D47A0B762B4E9EEB85235 +pk = 702701BF3674F2824EF3526FDCB0356222C384393E292FF2D6D90709E8417ABA6B8ACE3A569A1B513D29A006CF117A16B2B0978E880200706B2E913CE9CC0C9E4D0D239C538578D05D3A7716538E1527A02A9002E99B9C47B5CC201224E7F5BB25DAB559B9B0BC4E339063446700AFDB94426D4F8E34CFCFD65A62E1E2EF3BD375AAB11BCB284FD98EC717FAEABE811D0DE96E245DC7C45D8D60FA136A9C319D2D5AD77D010B872AAE5011B8F9F21CB54AE07985FE4E8EB9F41E118D2F7C77887B3E70B53718F1DFE0DAF1F17DD06E2EECAE612951AB03F38EB63800C23C3C4385FEE2C1BD670E20290DC7734F9DC4BEBFE546A91615A2899B0534A35E8AAD6D580B0A3B48DC60DBFB01A72AFE3591964CC5010396224D19D0837AF24BCE050A68C93F7CB2B29D3B470694A5AE337FD4C2DE384052B40F0AFBF3A122B242A3B1A6F1977E66D6A7BA1402 +sk = 63A925685A8AC5BBD918FAA33AC397D16D3E9BFDC871811E8827E576118AA548CB46A1B5E1A4B63823FE1C01702701BF3674F2824EF3526FDCB0356222C384393E292FF2D6D90709E8417ABA6B8ACE3A569A1B513D29A006CF117A16B2B0978E880200706B2E913CE9CC0C9E4D0D239C538578D05D3A7716538E1527A02A9002E99B9C47B5CC201224E7F5BB25DAB559B9B0BC4E339063446700AFDB94426D4F8E34CFCFD65A62E1E2EF3BD375AAB11BCB284FD98EC717FAEABE811D0DE96E245DC7C45D8D60FA136A9C319D2D5AD77D010B872AAE5011B8F9F21CB54AE07985FE4E8EB9F41E118D2F7C77887B3E70B53718F1DFE0DAF1F17DD06E2EECAE612951AB03F38EB63800C23C3C4385FEE2C1BD670E20290DC7734F9DC4BEBFE546A91615A2899B0534A35E8AAD6D580B0A3B48DC60DBFB01A72AFE3591964CC5010396224D19D0837AF24BCE050A68C93F7CB2B29D3B470694A5AE337FD4C2DE384052B40F0AFBF3A122B242A3B1A6F1977E66D6A7BA1402 +ct = C72AF9DB8FE0058FA999507EC3D69AEAFCD3AFBF9E6387CEA9C17AA8C00978879F12D50501CF452269A4E03F9949AAC344C66C1786ED00A7FC845BB14A89758A2CE4C994FAD5E02EAA0295BACAAC65E52BA78937C11121F333432FED33FFB236E9E639E80224A9A8B7CD98915E014664854BA468779676EB43B741746C866E2FF44AEDBD9BCAAAD11E1765AEF8BB22F650665EA148FECF45DF31B2A3AEF84589316E9E2002F88644E12B419ED95CA38632472DD17BA9E6269CA2C75E30857A1C1417985E4229C56C0C21CFDA48D90430B0F6D347F9DF7227D492940029E47B6AAB336DEF51D7C052681B5767C4DE900122736F959421DF1185C4E75FF67A9D09B73874758AD3A57C02AD9AC1F30FCFA71E03022F67663AE7F6F90008D753ECDF7F25375BF3E73C928821D5ACCDB33DFC9BFA1AE29B8FD11341FDE6F35579E19E56C002F6691E46E38801FF40F63ECD985E7A147CC4273A56E153 +ss = A345B90C57E48D5257A155B917500E62 + +count = 57 +seed = 4142237070C216BCBE245A39BD9220533C97651D84832B26727855AD994A0760C52B9319AD404693E4248B8C5FF324B3 +pk = 3701DDF09F3DD9D871D4D663EFC9DADA11FFCEF725F363F544D68DC9453C0D1A39EF81251D101C50CF2D6C428FAC2597B11824D3350C00D8A42F20B9ACA29379375DF81BDA41FA4B3F17F3363DB150CC568E9436C29CC51C99D13C1E0A76CDE29BE2BDE30232D11542668809C001DA076B316F4B2511016001649C08EA73EF7F0701C16EB62798575DC713697A8B0550BF30A63E673C0E3E968E8788D784522D519EDEB60036415ED153629685CC8BA3DE6E23350933AB3E552102FA940884290E7296C8A948F38A907734C7493BA93392494A67DF881CF8D342E5015451FCCCE54ED98EB606A3ACB6240624856537935ACECD0546BD39353495B1A1B8231C2F970B752AEDA92D5E7891F52CBCE841803CF7001274ECD6397F1A8B27AABD9470BF1D18AB9AF401CB454E158BFA3960D4624F072A14EDBDCCDCE63410FCDC1D762B6AF0DAE11A1B4D7100 +sk = 6A1AEE5E708C1B47F02BDACCE4F56C86CA9F6F64AE7EB3C493F0D576ADACCABC44FDE623EBCBD94785F31C003701DDF09F3DD9D871D4D663EFC9DADA11FFCEF725F363F544D68DC9453C0D1A39EF81251D101C50CF2D6C428FAC2597B11824D3350C00D8A42F20B9ACA29379375DF81BDA41FA4B3F17F3363DB150CC568E9436C29CC51C99D13C1E0A76CDE29BE2BDE30232D11542668809C001DA076B316F4B2511016001649C08EA73EF7F0701C16EB62798575DC713697A8B0550BF30A63E673C0E3E968E8788D784522D519EDEB60036415ED153629685CC8BA3DE6E23350933AB3E552102FA940884290E7296C8A948F38A907734C7493BA93392494A67DF881CF8D342E5015451FCCCE54ED98EB606A3ACB6240624856537935ACECD0546BD39353495B1A1B8231C2F970B752AEDA92D5E7891F52CBCE841803CF7001274ECD6397F1A8B27AABD9470BF1D18AB9AF401CB454E158BFA3960D4624F072A14EDBDCCDCE63410FCDC1D762B6AF0DAE11A1B4D7100 +ct = 3DC947FB0B86A9024DAE01A470AE88862436083EA0BF3ED41E673B113E3CA290EAA3C0F938228B2A7E1AED58E77D0A574B71F2123F7400BBB55D5C94C7CAB38C4C79AFAEFEBAD6C450632D617B0FB232CD1B540B3DE896F7E28CFFB4F94862D7A61851E652AFD761E30304741D013B6C52F280CBD71E8A1D349F8E8A7D266564E3413FCA60C046DC9218F23EF36C3CE2640987321AF768A6075D39D2822F66C0C1F1D12A00185622BAAAB8C8C748BFE834EEBDD45A3E50E15806A163626331DDE75A354EF120FC8589B6F82EC056CFD236E4C557684CE030466A6C017B4605D04E742C4365094FAF72C9CCD18890DDF1CFE6E757DE9D22E33492571BCABF08DB167DB99477494B099087A7365149A170126600568F6148753A37C0F544B22E23119FF3AE7C858C9FAC3A72B06F769C8F37D034395815F5C3555197E6F1F1EEB7F667D653C1F7D7B1E600843381BE13131C2626FB7C9E473FDF50 +ss = 48F4CAAAC964251E2A039063C206E99B + +count = 58 +seed = BD334D7B7EB14E00E68863F2E5551A095F8AF10681C28353FD19B9A7E70B8BFE266840860609008A567ABC66316C77CE +pk = AD5CA25928A95A69099DBD0E2AB67494CBE404741115FEC47EE8D44588EC55323D633791020CE18C4CBCF315A63109DF9EB41C9CF37A00D73EEA2F67DA46E38507567740E4FB0FFB31659995E1F24BA21A32A27DCA0963B03F880588CE54F5C08FFE81F8480C86D0AA83A7E8C700B8A4A8C2EA85DEDB049AAB634871C40DFEFE3E66A123203F3345223BBE04F35CE4F5053FBFF8D2087B3080F67679AC6A35E9681CEDD801A91A45B6324D09E48126551EB613085E708198E134742D771DCCBEC10BD249AF80D3EF8B3074B85395B866B1A9446A8390ABE7FB0CA70088CC702018182B6BA52B2F621C118F95D691265FDA98EE072B2F61E14C835EDEA8266A0864EEC302BA7A75A2E79D7ED8D74568FDA2BD01885197037A0C99E0BA2822F95046A3A3938977E0EB8930DB4D3B130B627CBC7F6B49FFBADC5ED1092B2800DD283215DB044728AC939201 +sk = 6396B328B100E4C7F4BCAE69875EDEA1B1947083EA19DE32004F49E8696F247C556CF33F78745F7DA7D50001AD5CA25928A95A69099DBD0E2AB67494CBE404741115FEC47EE8D44588EC55323D633791020CE18C4CBCF315A63109DF9EB41C9CF37A00D73EEA2F67DA46E38507567740E4FB0FFB31659995E1F24BA21A32A27DCA0963B03F880588CE54F5C08FFE81F8480C86D0AA83A7E8C700B8A4A8C2EA85DEDB049AAB634871C40DFEFE3E66A123203F3345223BBE04F35CE4F5053FBFF8D2087B3080F67679AC6A35E9681CEDD801A91A45B6324D09E48126551EB613085E708198E134742D771DCCBEC10BD249AF80D3EF8B3074B85395B866B1A9446A8390ABE7FB0CA70088CC702018182B6BA52B2F621C118F95D691265FDA98EE072B2F61E14C835EDEA8266A0864EEC302BA7A75A2E79D7ED8D74568FDA2BD01885197037A0C99E0BA2822F95046A3A3938977E0EB8930DB4D3B130B627CBC7F6B49FFBADC5ED1092B2800DD283215DB044728AC939201 +ct = C3A47DC452E79684E7A511CF7D139688C2BBDEED755F718229B56C7C80EE03CA9BE48AF78D70921068D2492AD0190C1758C185E66FE700A8A717FDCB49DA688098B337D2A1DB691087DE8FE3AC7292BD87DF02B884CB9465A377B69D6E0B030C0CBE7CD3DDEFF9CD544052148C0058977F18A2A5264209DF07DB5CFB29A44473A00D833E8F1634BE13A13563015745D8C8132F5F757376AB26CA9715B23F664E1D2DFD5901BAE51C8E80E3BC227A964697D90D7D08F10C088D5E287A16848ABA827DFA744D4645DA78F8AABE2878913D2D8FC2C6AA18EC220F922801BB549A9910DDCA0AF9B64EF0587F8B970B4396887EFB69C067ED1492C4AB3C60D039171F41AA5EB796A15E0D1A08835054F7C06A697E00C02BCDCE04320347CEE14C1AD829BE6DA4F09558447569869D1E316CF9CFB87F739F2B720F52E50EB750965F27E29DEF1CE079BC402001DBD04830957773FEAD0A5262F0B79131 +ss = A5611782265E1932DF3B7E736F40BA3A + +count = 59 +seed = A0264C58AB1F2CBCB212077FD378D340307ACCB31F1312137CF84E3D3135044D4EAE8BD38BC3E540A0C14D46458F6179 +pk = 8CA6ABBED1FC3E64B29FA9F87E149A906BB5FC7C69BB386ABCCCD2CD1755EEF206FD9F801139F62BBCDF136B9AE3F1076B29584D07AA0183A6A1F092976FFC146D2022D77A0F132DC1A8E32E510729B00CA76A172D41A553072177D2ABA1E087D7FF1EE4642CABAB83D9C9B1EA0144C76374657D4BFA797CBE29C0F2CA863A4AF30EFCA9DEEB76EE64E823A6D27E73DA326A65D49B4DDE6AF41594CBDADB27152F6CD71D023B719F7CF53C9DC2262C6C1910284264399B75AF086548FA8F955D2BC3467EA78E873B200997AD4CE2C6DFDCCD9DBA90B7B2D276837301AA1B4F88864096B0B4A4E0A4F8542EDA77DCB92AF456D930E29040D8ACB57C5813E6E051FC51A4D9537B51FD5182656D86E08EAF01EC01925A6B7BE77D58C998B3D21C5F64DDCFE561AEE1732B01C7315BAB1F4AFE0400789FA36939EC389F9964FC735C75B86B6E64D041443901 +sk = A453BCACDD2B0D4646009E5ED451C3C4E810FDFF3E1086663F6C7B489742305D34B1FDD7159072FA736B97018CA6ABBED1FC3E64B29FA9F87E149A906BB5FC7C69BB386ABCCCD2CD1755EEF206FD9F801139F62BBCDF136B9AE3F1076B29584D07AA0183A6A1F092976FFC146D2022D77A0F132DC1A8E32E510729B00CA76A172D41A553072177D2ABA1E087D7FF1EE4642CABAB83D9C9B1EA0144C76374657D4BFA797CBE29C0F2CA863A4AF30EFCA9DEEB76EE64E823A6D27E73DA326A65D49B4DDE6AF41594CBDADB27152F6CD71D023B719F7CF53C9DC2262C6C1910284264399B75AF086548FA8F955D2BC3467EA78E873B200997AD4CE2C6DFDCCD9DBA90B7B2D276837301AA1B4F88864096B0B4A4E0A4F8542EDA77DCB92AF456D930E29040D8ACB57C5813E6E051FC51A4D9537B51FD5182656D86E08EAF01EC01925A6B7BE77D58C998B3D21C5F64DDCFE561AEE1732B01C7315BAB1F4AFE0400789FA36939EC389F9964FC735C75B86B6E64D041443901 +ct = FFFC3BFC6FEE16A0657F2D379A88E6ED0E40DEB71C6D703DB7699AE914F5E54EAF974221D93A6160294DEFC2E4D0E45A2E73345477660050B3121137F1E6CB4359EAA0799BFF98297FD0CF2AEC3530A9ADE6B651FBAC09CBC15D96AE2D0155065E1700900F7C04CDC1C23C5B06004FC9955C8E9464E36C2FB2D3022288B937805562DA27AF2E3F8D656BC9CB04B83D1BB71259B6F9D281CBE0D93939C0E00B83DD2D231002B230A362BC27DB27729D6C64CEE188EA9F019AD77D1E8FD38FD8337B8F8C132137B6786D3B0D55677C5BAC3CF590462EEAD4C9C2EA1C02209AC0DB71C164123BE68CCDB62DAD9731C034FB528D05D16F7D144644997E33699DEEC61D73FCB06463D734A454B2405D679EBF230500CBA5DCD4B4399525FFDF252D3C7310310F6758897FC3CD838BFA26E6316C8DC8E536509D31EDFB6D017A19A829496240816134C46D2502C33A13D0612EBF343F71E311A24B7702 +ss = BBA5BD08A7BD6DB8620A1C1149B00D03 + +count = 60 +seed = 99A9CDBFC674AB3FF2C64CDED7D697A6E27A767434A47AFF7C3FBF3C6A22D6043D27868955286A13EFE3DE36D22EC48E +pk = E97E2291AC4EDD6C891CDD83254AAFFCE54E17DA2B5A2FF5DE80BD3099FF430422F894BB444FA8D932B42847C24C307618AC07711338000C0C47E13241A82DC36DADEFC9A734E15487BA0A5158C4BA24E1AB09D296AF9BE33BB66357EF74BBA7C6F6C26D253850A2D5B7053ABD01C967B1D444B830C13F2D84595991027CD057264DA437C40FF680292E3CC4B6C1532205C01A8AB1260276C1C66332D7F88DC68177F42C0155B3E4B612DCF0E7569CB58290D34E03F41C5A6971BC9AE2B94B8DF7BA89C315024834B01DEA17150753A18ADBE18BF7E34D9918E3AD014A5F85825E6AA2A0694D69CCEE5E65EDD3013265DDDF21DEF509A70115158B3B873DF1E73F185BFF1A297384C8531886E66C4A4897EA01C978364EEDCBE2EBAF9C9BB572081C381125E09DD4A539B7B6B4603D3AA145CF1A3C5057963D41981BECCE8D4DCBC316B952F252FA6F01 +sk = 47CA2B77C5B717F423222C2730CA5CB978B7B859D042C0EF174CD6EBCE4C1FED3D4248A48506D73838F8DA01E97E2291AC4EDD6C891CDD83254AAFFCE54E17DA2B5A2FF5DE80BD3099FF430422F894BB444FA8D932B42847C24C307618AC07711338000C0C47E13241A82DC36DADEFC9A734E15487BA0A5158C4BA24E1AB09D296AF9BE33BB66357EF74BBA7C6F6C26D253850A2D5B7053ABD01C967B1D444B830C13F2D84595991027CD057264DA437C40FF680292E3CC4B6C1532205C01A8AB1260276C1C66332D7F88DC68177F42C0155B3E4B612DCF0E7569CB58290D34E03F41C5A6971BC9AE2B94B8DF7BA89C315024834B01DEA17150753A18ADBE18BF7E34D9918E3AD014A5F85825E6AA2A0694D69CCEE5E65EDD3013265DDDF21DEF509A70115158B3B873DF1E73F185BFF1A297384C8531886E66C4A4897EA01C978364EEDCBE2EBAF9C9BB572081C381125E09DD4A539B7B6B4603D3AA145CF1A3C5057963D41981BECCE8D4DCBC316B952F252FA6F01 +ct = 3613BFD6D40D49A140CDE59FF2AFF193B5C6A5E5699E25AB2FE0FD4A495B68E3FBF4C3FF92440462C3881D533D289619D63D7F48F05400F70F1977A6EDAC7BDBA93E629032B0BF5501B7BF17FD2B3C1BF2A2273498F1A96620730CC4EE61E76CF0680B52DC49BFC4CAF155FB9C00AFED4CDB9DCEEA14389E1E6A174A8D23E863380E06B3DDBE07BF19CC88005C2A68F82CA2462FEC058D11F7C44811363E7945705C3E710085443A799503AF24CC49688C6D8900E27577E9ACFB18601F383E36143C36CF7F013F97024598B64B3EB1AA60738AF99D00FDDD66105D0114932A2E7F50C4A38269C81C97574A43821FF7F53655F1264281FFDEF023D4398D56084958C27B8EB72729C0CFAC6FEA68618683CF6C00D9C8A17F50184135053706013D0FAB0B11E3CBCFF39ECA75A02980A178800A730AD15308714481FD9BCF733408B17EDF38661432F48101430614AC37977237A2E574DC450EC6C4 +ss = E72DEB6A7678A71CC4986737F98204E5 + +count = 61 +seed = C799D57B41F28C5C446DFC58A5AC6499C4BCF3C162AFD2B09A16549826EC2A6F689E44BAFC4ACC82F5D6AEC23F4A3993 +pk = 727B0124AE457E9C7FFAA43B1C7A3110983E6B6B81F86317616432DCE466B257BFF20FE0ECAF6FC44F967784D2E6F04C6A80314769AA01CE1B91064D34EDE360D599F301DD2DD120F1223D4EADD07F1F533CE694C78EDD2315ACD642F6ECD5A7A451392C2B1B40EF48788AC844011587B1EFE4438ECF17CC9136A0691BF7659CFFF0DBFFD657F89A9E61765E6CC69B968DFBE82F5BCE4E4722406E9D1DCEA63E00953FB401706C9BF31F785E313B0DAB61DFA2DF687E373F9F9CC8FBE8A14FFDBAB52EBC1E6935AD9C7EF14C07345AB0D570ADF8493B20A9ABAA6C004C1CBC4C938C9097F7ACC090F4452DCCACAFF3E9911999233D3A2309792107B0446A39E9E8FAFABF8376AFE9F230053B500E517CF15101186D4C219EEB85E15B11D74DF2286B437C9C7D34BEDA9BD03D91F764AB6DB04AFE4AB4DD94F710FC366DCBF68F8E1467C06189929E7400 +sk = AAF6EB40E596A5E3E8218871E708B0897C0AFEEA370632D3C232B25961508A363FB76E44B1ECA4C8A54E1B01727B0124AE457E9C7FFAA43B1C7A3110983E6B6B81F86317616432DCE466B257BFF20FE0ECAF6FC44F967784D2E6F04C6A80314769AA01CE1B91064D34EDE360D599F301DD2DD120F1223D4EADD07F1F533CE694C78EDD2315ACD642F6ECD5A7A451392C2B1B40EF48788AC844011587B1EFE4438ECF17CC9136A0691BF7659CFFF0DBFFD657F89A9E61765E6CC69B968DFBE82F5BCE4E4722406E9D1DCEA63E00953FB401706C9BF31F785E313B0DAB61DFA2DF687E373F9F9CC8FBE8A14FFDBAB52EBC1E6935AD9C7EF14C07345AB0D570ADF8493B20A9ABAA6C004C1CBC4C938C9097F7ACC090F4452DCCACAFF3E9911999233D3A2309792107B0446A39E9E8FAFABF8376AFE9F230053B500E517CF15101186D4C219EEB85E15B11D74DF2286B437C9C7D34BEDA9BD03D91F764AB6DB04AFE4AB4DD94F710FC366DCBF68F8E1467C06189929E7400 +ct = 703BB1DD130A7087003CD296E13FFA7CE1AB2EFA024EB02ECBB6054C2DA0537317614E1D075F1F0A03A289B48212EFA3E0FCFD6D00DF009E6D779B03BC0EFE5C1FC44327E710FAB872A967B5A53D129AF3336FBFD92BEB7361DFBB019DC19630D756D7888095DB3396DF579D200064B53C4DC5DE29A5535E77B5C5BACF30373F2D85E29FEB60ECBDF46ECE95DAEFF20D1331DEF5F53AD0004385275C206A1AF5BF46914D00BB9D1D4C631000C5FDB4ECA685E0C14FA07CA70795798B801CB05658615A9B11B953519A6A15E7BE7A9D24665F3D0146215A3451BCA000E1FF18EFAC26EAA35A084C4D4644DA52D3E69357C3E51A6C3DB78B968A2046DC7727BB115B24C92D63D1E0DBE440F96B1E3428BA3A7801F4190D85804D261D1613A361F529FDFA77579CA65586E7E6DD91E9F0B7B376597745BA0821176F66B1613B84B973D0B9EF62E41741C6013AFCE7D7BCFAB307E3543041847B858B +ss = 14E0D35F4EEF91D784C700B5C9E99296 + +count = 62 +seed = F7AE036A0176A9DE9A036A542DD2840033277C44AE936D10B768566216DE9D4395CD42B116873B69D9804BA6CCBC05D5 +pk = 0D6F148903FD537FD294950DAD7FC52118B64EE1150DBCD5C1AD19C48598FB17178313D61F22C4EBBF1B6A8E636630BDCDB533E6E66601D84ACB55038F89DAADF7A1F2F7EC9BEB5AE775FB64BC0A1D1A43AF3E76C6C910A565E8507947450016782FC98C237440EBA4F1064809004947295949BF56B588AAA379E43C700FB5EA93087451A2704B725466682251A00456A73EC81DC80E32815E4B6C74F0A3A860326F0C1902E633C345FC06B71367A37308E9D83CDA6AA6C7D6F22F93758896DB2FE0B913C31B9848895717545E8C51F1AF850B9EA6D398959FE26D00E24F7309C3CF818BFAFD7D25F2C4D21BD071E8AE3C085D4E4E5F7A4981A6D108DD4DC39B394E36ABF58D9CE0894980FFA2C99FF0633301C86174ED24E5CF936D8AAE331919567D0989136AD54CF66BBF5E696560234BB883E63A6E4D17EA264F9B02AA9491F027CF627FE00B4F00 +sk = 6500F32C93415CFDBC0BD31D78D5BE95CB4DD6F6DEC81902BB89A14C910D5DE6303E7F605BFF6153D43A63010D6F148903FD537FD294950DAD7FC52118B64EE1150DBCD5C1AD19C48598FB17178313D61F22C4EBBF1B6A8E636630BDCDB533E6E66601D84ACB55038F89DAADF7A1F2F7EC9BEB5AE775FB64BC0A1D1A43AF3E76C6C910A565E8507947450016782FC98C237440EBA4F1064809004947295949BF56B588AAA379E43C700FB5EA93087451A2704B725466682251A00456A73EC81DC80E32815E4B6C74F0A3A860326F0C1902E633C345FC06B71367A37308E9D83CDA6AA6C7D6F22F93758896DB2FE0B913C31B9848895717545E8C51F1AF850B9EA6D398959FE26D00E24F7309C3CF818BFAFD7D25F2C4D21BD071E8AE3C085D4E4E5F7A4981A6D108DD4DC39B394E36ABF58D9CE0894980FFA2C99FF0633301C86174ED24E5CF936D8AAE331919567D0989136AD54CF66BBF5E696560234BB883E63A6E4D17EA264F9B02AA9491F027CF627FE00B4F00 +ct = 3CC75AA604817508EBA5C04D73D0593B95A3ED553F4D26E404F7BE6C2372C1E83CD5CE5265BFBE1F3AAEE586CB17756441F6673CE90902AF24549B7B7376D07BB4519BABCF12DEC564CBAC7D48C0DE6E9BABDDBE03268E8FD605BE8E839B00794600EA11F0DB8FE5FD2EECFB8A00BC264283D425B9FC312371C565B64D2DF1066360695697E895CCC356B2DF78083F450D89B790AC17618B6EC4151CC4BF467BF1364E92017403299D6595EDEBAF9584684CC2D8C759111CB75335A3C4FBE78781245307B3ACBE19C50B157F3898C92EF84A34AC1E4919B343816001FDFA4D0713D29543B3D9E738E7677CA978ED575460ECBD62CE874D630E276BCCBB3BF95D8B90F21FE95D9E2275BEEEC2AD9A9109F6AA0104FAB9F2AEC92CC70F612954FAE3DD43AB82D7604F56C2B68E98615B6DDA1183A72A305E74D092D3F53E8E44DD1650F0482CE9D3CAF800B0EAC4B9C25048324BB2F81545741AF5 +ss = 3588D259EA898E25FE7883554B9B4A77 + +count = 63 +seed = D995D38F934B6E1A7CA77C9522E3D037676CC939B0C8BD4B84394B3DC91A791F09D2D97199258C9943DA955E7F7B26FC +pk = 22E6AD3701B91F9AE1D91BBC7164C6733DF4A4E08FAB8A8DCDAB3D6A5EF86C6A2F0DB050A5A07C95CDEE030261EA73A1A12767BE6C5E01070952A58D80098114AF8957E76747FD2F06DDE6BE794A089211846C6BD6A329A213A5B2F401B493B756D30637581DCF0BD48C88FEE7016FE419944906487E4452F4AFA330CC61C035C1F64A9B4D59439BF417F936FC992361465D512985528140802AFBCA00A51917FD18714E014CACFDE6D1A3CB4195B13A1AF7EBED68751AF5C52B19DC5689F7E4AC1253671B6C15C9552F117D7BBAFEC770AFBBB528E62B9DB933BF01918526CF61BBDCDBE2AF5301F5273E649AF2AF618EBE5167F8E33B5F48B8AEDE72E4B49A32CEB4D8FECBA5F2B7D90C9E578BA950A54D0055C71A66FC6B4D16B59ECF438D20E13360CCCEBCF4DE9A90BAC2056B18C64D5629E2201882977B17717A07B8A03E6D64BD247A98BEBD00 +sk = 7643CEF2D62CC5AAEECF754653EA6229D02532A13919CCBD7622339742B0F44C697D5D5931C43D983CD1E50022E6AD3701B91F9AE1D91BBC7164C6733DF4A4E08FAB8A8DCDAB3D6A5EF86C6A2F0DB050A5A07C95CDEE030261EA73A1A12767BE6C5E01070952A58D80098114AF8957E76747FD2F06DDE6BE794A089211846C6BD6A329A213A5B2F401B493B756D30637581DCF0BD48C88FEE7016FE419944906487E4452F4AFA330CC61C035C1F64A9B4D59439BF417F936FC992361465D512985528140802AFBCA00A51917FD18714E014CACFDE6D1A3CB4195B13A1AF7EBED68751AF5C52B19DC5689F7E4AC1253671B6C15C9552F117D7BBAFEC770AFBBB528E62B9DB933BF01918526CF61BBDCDBE2AF5301F5273E649AF2AF618EBE5167F8E33B5F48B8AEDE72E4B49A32CEB4D8FECBA5F2B7D90C9E578BA950A54D0055C71A66FC6B4D16B59ECF438D20E13360CCCEBCF4DE9A90BAC2056B18C64D5629E2201882977B17717A07B8A03E6D64BD247A98BEBD00 +ct = B5D25E6449FAAF1A85254AB7F3AA11889F3BB222AAB8B0DF68699CCF394922C0C32965EFD1274A066924261E88225E5BCDCDE4B6DD9B00B10B98A5CC2E5D2A01CEA357F63B5855C4D283AD44EDE0F25B1AC1D24C915D547F699872C8E7D53C6DBB9667D54DD598CB6E5C511A1001E447080B1821220829C7BBBE3C170026966F1119A0DDC1354EEB3B9DACE5E6CBA5787434B6772200767254C056161CDF729ECC62BBA70016B12E6B5A67CE21500A048260862CBA87BE225D9A29231C0EC7EB7A58056BB2D055C676C702FE1655DE177B3E04E97B56AEA0BDD6D1007478AACA5F6BE4AEBCC46091798A5420E4BB7F51BD2AA62FD2BD55DBAEA4F7429C3543570965F5476D8CAB5CF5FACE07248281F5ADD2013254679D4AD0E98FFEEA1E44711887D3FD6C66C128764FC5515026ECCE2146EA39B732A633E3359DC95E17A1E14B152DCCC788CBCF0B021FE12ACD811D405CAECA9AB1B7B731AD +ss = 5CA9F51BE147CEAD8A910A5AACBE78CF + +count = 64 +seed = 5929F02A271725CB40200DE32D9D03D8BEA53B53AC83186C42C7F565CCB1CA508305D470850CF86E9B2C61A5B8CA1C93 +pk = 26E993E2F3857E5AD642A76ECDB1155A31E48C17759AB60AB96E54DF115D96626307A87FC2B201EE215E6EBAA8076674501C1EA54873003C0535CF2EB25C9B86DCA55367A037E30F5265AC3B73DC7FAA570BA0A288F933DCB37F1FAEC658E81FAB6D17713F798735177F20C81101D0FFDD14A9588B9CC7DBB7410E208C519C524F6909150C0825FCE0DD695243177B3B6446DE6B59E870B02811376F04EC5D2B03A5341800D81E2AE30953896F228538490A411BF97C287E11436DE0A96A61ECFCCF4FD8C26CA87345911553E1C9CB985077C27E01D4E6228DCD6101C1B9B6DEA614AE25ACD893257D26AD73CA67145067EF8884A31A7EE969C593DFD9525EA595096C199CE7DE16AC10C3BCB705713BF21300F2030FBD6D944EC69809BCFD91B9B3F08AEFE02A4518D942E327E54E33F5698AA798F3A1A73F9417FFCDE5DBBC2A9A3F6AF31652F7AA01 +sk = F8EE95521060C03BB8DACC79F7EB7DB61E3D78F1A9C5D3AB7B0F124E6595BDD2A1CFD3DAF7125AB513EEA00126E993E2F3857E5AD642A76ECDB1155A31E48C17759AB60AB96E54DF115D96626307A87FC2B201EE215E6EBAA8076674501C1EA54873003C0535CF2EB25C9B86DCA55367A037E30F5265AC3B73DC7FAA570BA0A288F933DCB37F1FAEC658E81FAB6D17713F798735177F20C81101D0FFDD14A9588B9CC7DBB7410E208C519C524F6909150C0825FCE0DD695243177B3B6446DE6B59E870B02811376F04EC5D2B03A5341800D81E2AE30953896F228538490A411BF97C287E11436DE0A96A61ECFCCF4FD8C26CA87345911553E1C9CB985077C27E01D4E6228DCD6101C1B9B6DEA614AE25ACD893257D26AD73CA67145067EF8884A31A7EE969C593DFD9525EA595096C199CE7DE16AC10C3BCB705713BF21300F2030FBD6D944EC69809BCFD91B9B3F08AEFE02A4518D942E327E54E33F5698AA798F3A1A73F9417FFCDE5DBBC2A9A3F6AF31652F7AA01 +ct = 401F10B5DB7B513CFAF8BFAD98ADA521D132BC0AF521E94794412A4AB88397C87A041191F5EF4AB65FA522BEDA2443990D3C40D7BF7500B71DE14FB97ED3D400334A1B7689E0D53FE3025B1141521A0E1A330C4886AD65DF816F98E22C716DBC1AB69638D8B92618D5AF51BC7C0119079DDF3415010E02DFB2A8E94561E4999A49C2952CEC4E0E7C78AA2A5BAE8AB4ECC6F9EB1B79B09DC69BD709F9BCC9E2899EF4C70C02F656A3C5180EAC9F45A0FCA863554A793B73AAC6CAB04348208317A7AE30D66C62B88A66BD0C31D58AC64A5F2FAC091C8A85645555A3008C4D621003819D34621F3DE662E35C3DBCB00EEAA840E787258F535AB9C1ABF9DFF07BB57BB6D03812DDEC800964280039B50C1BFF7601AEE4C029194A6689381CB43C4E303DB1F2CB09D86B5EB4C34F953CAE1A7868EBF652555D590309CA6A0A5C077720C50473AACC30C97B00A4CE018D8B4399B8B035AE66AE4EED06 +ss = 5E0D47D983AD86F377EC2B28DF453778 + +count = 65 +seed = 905074033D7B75DEB2D06A2F29144EB377B452534C5710632989F02D45312D156557E96D4486020826DB200153BC4A8B +pk = F4EB5756A2A7C3ABA281BE7039E0403CB305C7CF98546C78E69928898BEF2544C78679001E4EA5A91F76F6764B6EEA449B2B0A08537101CABDE41DB7E11717260ED2602A2D48ACFC5E1E5CD1C457CC2CA042A4D224A82F1D23731E03858BD226070AABECA820F5D8AB6AC7AADA0121176DAC0DD030768115083870D17F4B3ADD2BD48E7253A7644F7505CD1CB368E00C557ED4ADA00E7820E2C2D7AC35994603AF86C62B0199B312F5F9497C68973086098E39FCECA2DEE91F8F8B408B99E9FCE6F1311B8FCBDCB6A715B1C6A52A8A6E368B05D38F2B298C6900E601F858D5F0AE138076010B1257E9BCECDE939899B5B9F5473B150F0A2E7B9DB8357C0399BE41711EA5F9E2B60815BC2D95C1A92B14304700826E45C1D9886A64F411401B1566345B0921FD28FE8FAA3D15D93F28D9A6DB09CF0D40849691304384A338CDD261A0CFEA21701A949300 +sk = B8BD0493A882E3A49B4E0F6256FB1FEA0799EAD9BDDF2FDE63F0732FD66DAFA88AC7888939CEEBAD55F19401F4EB5756A2A7C3ABA281BE7039E0403CB305C7CF98546C78E69928898BEF2544C78679001E4EA5A91F76F6764B6EEA449B2B0A08537101CABDE41DB7E11717260ED2602A2D48ACFC5E1E5CD1C457CC2CA042A4D224A82F1D23731E03858BD226070AABECA820F5D8AB6AC7AADA0121176DAC0DD030768115083870D17F4B3ADD2BD48E7253A7644F7505CD1CB368E00C557ED4ADA00E7820E2C2D7AC35994603AF86C62B0199B312F5F9497C68973086098E39FCECA2DEE91F8F8B408B99E9FCE6F1311B8FCBDCB6A715B1C6A52A8A6E368B05D38F2B298C6900E601F858D5F0AE138076010B1257E9BCECDE939899B5B9F5473B150F0A2E7B9DB8357C0399BE41711EA5F9E2B60815BC2D95C1A92B14304700826E45C1D9886A64F411401B1566345B0921FD28FE8FAA3D15D93F28D9A6DB09CF0D40849691304384A338CDD261A0CFEA21701A949300 +ct = 7D2CB287ECA1594AE8FE77116C564A4E77DE76C2E4D3A67CE8CA134AEAD60F07F7B5C786D2B865751002EF92FEF134F1563B2FCFBFD8018D30FE640F235166676486D0244C43B97EF7D0237649160E45F7DF78EC101414603B74FEAF8A8F58C9CB2C5A22F1555541DC75DDF90501B22624C8D81240BE36AD591F189C19AB38C0BD9F575454A51E8D3A479253A1A3080657BF3AD0251AC9BE63CF45D32F0FDBA4403C9E1401F792BBDF038F891C46008BD9B414233E83CA76F65ED30999DD685732087F03D1246442416C4277413FA6511B1C64BF9ED296ED15CD5100F958396F5028B27F6F1B5AD52672EA16C73B35B16F0CFF1BD3B80CAB0B838237AD7B9576362B2D8909AF6ABDD872E50A73A2D7F705A80125425598039E5E5F34424A6C54609C7951F09E5DB6D11D6568419391EA4025498C412B5134780B2893B80CE6A909F9A685D12CA2966D0024C52DFFFEEC7CC69F799751250CBA24 +ss = 3F4B8410B799D38F26202CAC1B52A37C + +count = 66 +seed = A3E2E511AFA7BB560446BDADF67D2EE2E16FFC7BAEAE7EFB8C5455068BBD4E91BF9BE9D98B280072FABA7712C75B26D4 +pk = 8DA22097FEA967029BC23E0ACAF0405204B9B9B33D2EEFE2956E299D9A35B1432AA5D5904C70D5A1D52A7B69820EBD051A031257A3790099EF548478B458ED7FED9C0383D74B1CEF2675F2B1D2509BB1E28A8E26C9467FFF6C387FC911BCDC16BE5035911E3F82E3D8BD562ACC0109A627415E59A3D8D773264E1F634AB338025D226CCF4DA521875A4236CFC6960E65D71175015B98E7FF65CE3F02A1D79D31205311E7003AD731866DAB04CDD1C133A6F0514BBDE0B9CF9CA7A2AFAE0B8E28E92F935260FF9A07F996185FFAC3F18D977C9EF673A8908DBE7FE2004BE34CAA9C41895EFA374A8E2859229B9DE100C55D201FEB69EA258ED48E11C032347C47A21F27532864DC71FF375B8DED71B23B52B5017D89CC27537CBDF44E33CECCB04648C1A25BAAB95A5E3BE0822763F61DD65BC0EE9EFDD83C27D6E6E0248C7FD1094DDFBD531C10122F00 +sk = C0407E41DDF48D333978B89BCF2DB01EC941FA96362BA1E4733E332888BA4E8B1C5CE574652472A75B864F008DA22097FEA967029BC23E0ACAF0405204B9B9B33D2EEFE2956E299D9A35B1432AA5D5904C70D5A1D52A7B69820EBD051A031257A3790099EF548478B458ED7FED9C0383D74B1CEF2675F2B1D2509BB1E28A8E26C9467FFF6C387FC911BCDC16BE5035911E3F82E3D8BD562ACC0109A627415E59A3D8D773264E1F634AB338025D226CCF4DA521875A4236CFC6960E65D71175015B98E7FF65CE3F02A1D79D31205311E7003AD731866DAB04CDD1C133A6F0514BBDE0B9CF9CA7A2AFAE0B8E28E92F935260FF9A07F996185FFAC3F18D977C9EF673A8908DBE7FE2004BE34CAA9C41895EFA374A8E2859229B9DE100C55D201FEB69EA258ED48E11C032347C47A21F27532864DC71FF375B8DED71B23B52B5017D89CC27537CBDF44E33CECCB04648C1A25BAAB95A5E3BE0822763F61DD65BC0EE9EFDD83C27D6E6E0248C7FD1094DDFBD531C10122F00 +ct = F221775D58433EF77F71C1627C026D70CADF30C93380FE22D08A573930A2B9FAE636871AD98E416C80FA86244B1E6270F8DD6636E6A7019C5D72AF128298754787C647422CA611374D5AFAF7E4518C2345AA885577E323018B0BE76F45611B88E696AD1E62AB427F71ED4EE9C401F5366E392945D3828C7E9F1A2F0CBC48035C923529628FB4D313633803F2DABB06A3ED53D73DA5E774B576E4D157B45EF2613235C65200B643C7A345548F1D964D0BE2ADA496A41A359634D5F7FB8A8DA444CF57CB0765CAE79C445988E20ECB4B3ABB31864E55D05D669A56D001627C302F75F58BE7BB465E71F549A5205FD14346B07AEC29B906B0917225084142FA7D90D0665CA67D435B420C1F051EE770F9A196A0007ADDBDFA4AF669F6D581A0AA71768438902AA035B1FD01A7B16CE45D76A509FC67FDC0FD1DE02AFED736D212F9225199FEDE5C1148D1007AE4FDFA31EFA408C63EAC035849A16A +ss = 19949A812632BA36C87F77EE12C9529B + +count = 67 +seed = 074AB1A37BA5A0403D8F68D26FB787BC2C90F5EF88F2A6D286C3E6B168ABD85D393D8225618608B8EEB301D26AF53BC0 +pk = D8F84A5C1BDF2EE99F1E9AD650743165C16BF1CBD7A47C6DB7BE95E6CBDDE9172C9A83719137BE189BAFCE89A1DBC37C52470F917DAD010CE18B4EEA8BA439FE2FD8C83E8545919BEE28FA608214B91B5EDD378FCB3AA42AD898BEE1E983763C3083DCBD7515FBA2C217C13AA600FA48A9D989C8DFC56A020D3BFE63DB0725495D5DE9CE9DA3DFBD125CF7AAE0D2B87E2557263B501B2DA712FAE8E7082AF0C06A1EF6220067F6D671CAB553D33A70453EFE727D8A8B0711E5E329760BFAE67765331D46EFFB1F3C085BA9249191EBB1B762DD5F4022A799FC9AB300F14329E72B942E7BA336D6F07820048AFA84B3B6B3CDE05CBDCC4C71786D2E80DB684B9C81E38D9E7F9629A5FF751641BFFE22056BD70076E01C4ECF36CF5B4E7C03C57040DF7A1360B123D0146A45792BD7B8881075C02947C56FFA0560561056505FEF3F073F9B32E59229D500 +sk = 334382D39164D1989696A2FF77B25A28D3AC131E0CECFB0900E8E52BAAFAB8AF11EA820B17D1BE1A497EA700D8F84A5C1BDF2EE99F1E9AD650743165C16BF1CBD7A47C6DB7BE95E6CBDDE9172C9A83719137BE189BAFCE89A1DBC37C52470F917DAD010CE18B4EEA8BA439FE2FD8C83E8545919BEE28FA608214B91B5EDD378FCB3AA42AD898BEE1E983763C3083DCBD7515FBA2C217C13AA600FA48A9D989C8DFC56A020D3BFE63DB0725495D5DE9CE9DA3DFBD125CF7AAE0D2B87E2557263B501B2DA712FAE8E7082AF0C06A1EF6220067F6D671CAB553D33A70453EFE727D8A8B0711E5E329760BFAE67765331D46EFFB1F3C085BA9249191EBB1B762DD5F4022A799FC9AB300F14329E72B942E7BA336D6F07820048AFA84B3B6B3CDE05CBDCC4C71786D2E80DB684B9C81E38D9E7F9629A5FF751641BFFE22056BD70076E01C4ECF36CF5B4E7C03C57040DF7A1360B123D0146A45792BD7B8881075C02947C56FFA0560561056505FEF3F073F9B32E59229D500 +ct = AAD9E86660249AB2675FCBC20D2A552946BAFC415EC2C1B3F8E92EF124613FC8F723DA7079A2F4C94503DA3B9349332C2DA847A126190177BBF0961C03816488B76342E8365F3277FDC1B395883D1408C2BB4488D677973EC44D708350717D6331B723CE0687013DD72D31616600C39E4BE1A726E25308C5F63406E23D2A6CF9880223F99DD006993DE133C1D5B8B9CB0C524FDE13F2016E478FABF4AC3CF9FDC781AD0A00202F2036EEA45C5BCD812F39C31F33054F708F6B305A10CD36912BC895B5BD828A89A0B7D0C3A878955D5AEE8B93B753B4AB6F34BCB600DE6E94BB7B4A417F7467DB1147F431F6BBD82FDD3C0DAE862D20F4A1FF8A08D89E5D375B794BA88CE9EAE65D5B61889B4F6C255264F80023DBB375FCE467082B72D2F37C86CBEF3266C7D3B42F8B3DF7A42CE75DC43B6DD0F2686B1DD577D70AB0316507BFA5C675449F31B6D201B537C869E53E6CB1213F772576EEBB8E +ss = 5D20C1D82577713863D76ED5A40C184D + +count = 68 +seed = CC0C86CC0ABF86FA21899BE1953913C00E7C46E6B5F730C4E88B3C034012763981D7F14459D3081638080378348856EA +pk = F5BF4C2956BE430CB1FDB803958EACC92796B70F561ADB4C0D0BD29CB9900E82ECF627F800F83D1A153BFA6FBEBFCF6027794206199701B924370B2F6150EFC12AB47707B1EE32729B9B083BB1736CB2FBF7BDD3A573AB9D6A755F8BED02B5EC4FDF4DB16246921DD13F1197620158EB926CB4A9EB0BC97A2E33134BC38F0394AB895E573F0D3A98CE9660C80FF79953F293FF67473EBEC935062F09D1ABE15688E8C0AD01A0BB965AE1114BA2854EF9826ABBB2A86D995781023124B8FB1C4B22D2B69E1CAE735AE45FA313F9FEBA82B270CC6EF64866EAF18379004FBEB90747AAC4DBBCAF8F7682EC5D5A730A4E4936462FBF061C84A60AB3D741BBED0538381E76C84CE29B3AF4C7BDD574700159733F00E346E9D251ADF2DAA6A8D99A50A8BA116F91EE461751C0B116EA47699BBBDF8A0208F5EC2A8A681522085CD8654840F2DDBCEC44EE8C01 +sk = 6995143E8EB8A6E93840F76EEC844F671D3273A811D6EAF877FCB3A3C985593289572FCE4CAF52D13CA6DA01F5BF4C2956BE430CB1FDB803958EACC92796B70F561ADB4C0D0BD29CB9900E82ECF627F800F83D1A153BFA6FBEBFCF6027794206199701B924370B2F6150EFC12AB47707B1EE32729B9B083BB1736CB2FBF7BDD3A573AB9D6A755F8BED02B5EC4FDF4DB16246921DD13F1197620158EB926CB4A9EB0BC97A2E33134BC38F0394AB895E573F0D3A98CE9660C80FF79953F293FF67473EBEC935062F09D1ABE15688E8C0AD01A0BB965AE1114BA2854EF9826ABBB2A86D995781023124B8FB1C4B22D2B69E1CAE735AE45FA313F9FEBA82B270CC6EF64866EAF18379004FBEB90747AAC4DBBCAF8F7682EC5D5A730A4E4936462FBF061C84A60AB3D741BBED0538381E76C84CE29B3AF4C7BDD574700159733F00E346E9D251ADF2DAA6A8D99A50A8BA116F91EE461751C0B116EA47699BBBDF8A0208F5EC2A8A681522085CD8654840F2DDBCEC44EE8C01 +ct = 0E19214A955A12BD90B22ABFA1AAA39A4E300368F2DABF8E68BE96AFF86FE09BDAFF292F8643937E4DB2B620083034ED5B8F683DD18A00719D5B5E92D282C53DCE84E912BFFEF6225A6642F5BD66610419D86FC8A87B277C6E85B52074894AEFB522FA2F54CE3090C9EA63E5CE007FAAFB11D8A2AF4687183FB7BCD7E1293392BCA6CDD7E4A27AB4D4275832A86D0256A1684607379284219DC05779AE937E488207DAA20154717FD0AAA43366498E50016394243697F0206FEDBD45A498498C8F2096596DE5333B107917A475E3362BBD8C7BF769CC52344AF3D80060769932AC3938E4D0143B85FAF2E99AA26016D76838520861AE32C9867DB8A6081BE5A2482C33B2382BDC938F94F440FD5D0F57712C02497C64525EB1E820E4C70CDF5869A11E7E9C8F45B4C0A0D6E0483A4CE0F445E1C33D73006AED8B7CE3902CECD17417E69B780AF62B1F024915C5527ABA7379E7C78B66329E7336 +ss = 3774A74D416427DF3F63B8AE681FDCB5 + +count = 69 +seed = 6D5A7CC326ECF3983C4E7683F45263A37F692F3BCD2D920E1FD9584350119E74F9A3F905F70D3E20318C1413DE2A0DEA +pk = 92E3CED10A5147663B0AC3C8FC40C4DE0C8B0377EA6CB22FFFD9566193FB6D55D1EE1FEA92E930336C4DBEC9975CE98991F8F094E4BE01B8E921407FBA15E0329700E7C9A347F33E0B772D89A5B769060FFC2654A60F2745A0A868EA7282EEEE5608B1C28EDFF8B6AF3B4304060179F5F8E008B219F2F95A0AF63786D6F894AA5FA84E2E788B0B7B2F75B3216720272DFCBF96589871C0B3E4A9233D751E475C52A5E32501FF8E46798B1CFC95E611B64F9AD6A44ADF6378C2632204BA1F3AC81A715DA8DF4F785E5B1E0A3DD322D4EC084C65912BB99DD3B38D05000FD0FF843C17408D18C377F62CAC7A879F735E258DEAB3FB2DC8E98F29A5B00BFD5E2097D0F82F713ED60A43842DB679AD8304940BF601556E8FC925A9E95F383BBFC64B8E2068206AF2F509BCD49DE502E779A291DCE652654C31220CE494D943D838137B86FC693C79D700C601 +sk = 995EFF7E0D195C6D0533F3DC194D47E62611ACA46794A598D0E9165F7AD0ACE0D92ED09688FEED4E6841C90192E3CED10A5147663B0AC3C8FC40C4DE0C8B0377EA6CB22FFFD9566193FB6D55D1EE1FEA92E930336C4DBEC9975CE98991F8F094E4BE01B8E921407FBA15E0329700E7C9A347F33E0B772D89A5B769060FFC2654A60F2745A0A868EA7282EEEE5608B1C28EDFF8B6AF3B4304060179F5F8E008B219F2F95A0AF63786D6F894AA5FA84E2E788B0B7B2F75B3216720272DFCBF96589871C0B3E4A9233D751E475C52A5E32501FF8E46798B1CFC95E611B64F9AD6A44ADF6378C2632204BA1F3AC81A715DA8DF4F785E5B1E0A3DD322D4EC084C65912BB99DD3B38D05000FD0FF843C17408D18C377F62CAC7A879F735E258DEAB3FB2DC8E98F29A5B00BFD5E2097D0F82F713ED60A43842DB679AD8304940BF601556E8FC925A9E95F383BBFC64B8E2068206AF2F509BCD49DE502E779A291DCE652654C31220CE494D943D838137B86FC693C79D700C601 +ct = AA8B5D5D9D2EF286A112E9E3864F6CCB69E6294DB90AC11DF4D3543E4319C53F94A5296355C740A8299B2059FE6D8DD31C2457292E7401E9F2AC61E47AE55424CF9C18D4242C323622E5EB40DB6516D96D26B288798F2B1959788178B316A779E85243A8382711132D16DB72F50140EE90A11438296745055019C6BA0C2021BBE78ED43B2849E6A058B4DEF11D8A5998ABE5A113ECF53A26E2734C9F1F9240695E152E9C00CEBA823145112547577C523DF178261D59560438C2AB80FAAFBD807E0B2F709D7DF6B6FAAB4DF83D1325841638C46099FF193AC61DF0019FEE296545483C92A6E8BEA5BFD26CBB42B95AA773FDCBBC3945806C7777F5BC5079BD04DB250840460258B943ECA32886FAB610C34D00CC93CDCE378AB010FAA29AE2718D0766DFB84714FF8B030451789D357F03A2EC6FFDEC33CA2C27E4721AC81BBDFE889801F4E2994B7401B1CD9600F99443637765D280334E7171 +ss = 202E3D6D3132D36F93EF6BD8BA489C3D + +count = 70 +seed = F68FC0314DEA88F66AFAA76E6C9B6804B13D4876924410D1F526FAC59A62E26C560B125B1D0F8B461F1FC2E351EFFB4F +pk = 37496914E4EC49D39E6019E283D16B3984ED7587324CA8100F35A22EAFF4ABB8A98FD1957EF82AE80450A25FF5BF77DCC93A0DC8246E008E3454F6DA37C343A65D41AD1CDDA30E27FDE128DEF7A8BB7CCBDB44C8293F113EC47D7C5011FF4FEAE756282D47D971E6A0214CCC5C00C796D5BC3E514FC5A3707FE5104B5309914766A4774C313A8FFD4357D1F42ECEE8DB4C7D2D0A54E315FC003281045DDD92E8A82981EE01D43AD6DE2CBE1932EF1F26CBFDD0CB8C38F9576D4D494C3CAE8211930B86B6E8A061AB9B26DA36F07913B4CE80774030910127A5E815025EB6CBB27FF56D31A895AE5B13FA282B52CEFFE555437C67A40AD109EA70DC763243B5A3FAFD8FD31E172E8233F0EACE410C9B1CD949018745A6909F862228CBA49F070D60C2349121758D7D1BDA506AFB497D22998B3AEC1AEDE66E195DEC3A0EC4F3D5847889926538FBFDA600 +sk = 3E809EC8DD0FEC0D911A4E3FAC20F70F50C00D09A1E90D4A1B9480A64DBBA9BFC95372B0907A0697266FEC0037496914E4EC49D39E6019E283D16B3984ED7587324CA8100F35A22EAFF4ABB8A98FD1957EF82AE80450A25FF5BF77DCC93A0DC8246E008E3454F6DA37C343A65D41AD1CDDA30E27FDE128DEF7A8BB7CCBDB44C8293F113EC47D7C5011FF4FEAE756282D47D971E6A0214CCC5C00C796D5BC3E514FC5A3707FE5104B5309914766A4774C313A8FFD4357D1F42ECEE8DB4C7D2D0A54E315FC003281045DDD92E8A82981EE01D43AD6DE2CBE1932EF1F26CBFDD0CB8C38F9576D4D494C3CAE8211930B86B6E8A061AB9B26DA36F07913B4CE80774030910127A5E815025EB6CBB27FF56D31A895AE5B13FA282B52CEFFE555437C67A40AD109EA70DC763243B5A3FAFD8FD31E172E8233F0EACE410C9B1CD949018745A6909F862228CBA49F070D60C2349121758D7D1BDA506AFB497D22998B3AEC1AEDE66E195DEC3A0EC4F3D5847889926538FBFDA600 +ct = CEF0E295D105A49B06C0C3FCA84751592114449890E5EE22A92E884D038989EDF10597D794515BCDB3BD8F3F04C808683275A522B80F00A09369EBDFCA1DAE1533C6B3AF1931E61BA9AEFC824AE2527392C2E7736453AE7E6906F28B292B94405504FFE115C4E0E6416566B3DC002731C35C89EC52CF54360D2B65D72B02C0CBCFC3E9512F091FD3C8132758FAC750006F2A0231B02278A119D9639136E3341372BE4AEE01E28FF6A2AF16E41050A7573DD06FFB3C21EC0BB069BDAF7C7230F86FDA5097DCC60C4AA18F5560C4470302D22C5E85FF48612C3FEB3A01D505C88B5688D6DB461356FE1A592FF21DCEDA379596BD8A9FC8E2ECDCA53A1E28E1AABB8DC54E91073948FD8641A08D71DACC6A7E9901482CBEC6DACC39E5FB773E8EF88519C0B81CDD721102751D2E552FAD03408263A46720E9027513FCF277D8F3F6B244E71C48E886984A0067926CE78EC3B09D7AFF29D49DE2205B +ss = 9B5515A30B0C0C147AE152BDFB20599D + +count = 71 +seed = A229218B0D51F58D915DF549901548FB0722F352C7470900E7E4D8399205764A319BBDDBD06C00E8C5932722EE5A404D +pk = 779C9EF12283079228CA485CB6BF4986186A8C31BF00F2D906DE37CEF7E03B6D322F518E5B5B7938440F9B3F1BBB56C148A5CC185BE50118CE92909B8CC652CD7AF99C838AB25B21A115669A536470E206B274F694598D421B808E076F7F9746CB86A02D09883C006BCB4C8FF4009E6265E73EB9520521090186A961CD9F9D8B116FE306EEC8F72CAC10A05D56E7D411FEA5F88208C96AA85351E0491AC36B7405537711011E33FAEB9AB94A63FA2D236664F837C4046936C3786875A00FF51E92AB77A7F81FAB18AA657BCCC8BB8BBD58388A3E4B23617F6E7875002D6B11CF6A3C0A64EFD1C1706D8FD4712F0D9A30F294AE8C406F4774FFFC752632830A514B1C2D83005DDBFB22738DA9C3DC22425606001BEB79B8AB56C78C1893FDB887F2E20C7C546628EF2D585166D1AC1335C701F54A21E85DF8FC48BD66D731AD157692FF3B2437E85F0D02 +sk = DBF1C465FFF3D9F783BD9EE61A573715CB9A1309AD27732313B1CE192CBC3D6F14BE491F71FDC193BB041200779C9EF12283079228CA485CB6BF4986186A8C31BF00F2D906DE37CEF7E03B6D322F518E5B5B7938440F9B3F1BBB56C148A5CC185BE50118CE92909B8CC652CD7AF99C838AB25B21A115669A536470E206B274F694598D421B808E076F7F9746CB86A02D09883C006BCB4C8FF4009E6265E73EB9520521090186A961CD9F9D8B116FE306EEC8F72CAC10A05D56E7D411FEA5F88208C96AA85351E0491AC36B7405537711011E33FAEB9AB94A63FA2D236664F837C4046936C3786875A00FF51E92AB77A7F81FAB18AA657BCCC8BB8BBD58388A3E4B23617F6E7875002D6B11CF6A3C0A64EFD1C1706D8FD4712F0D9A30F294AE8C406F4774FFFC752632830A514B1C2D83005DDBFB22738DA9C3DC22425606001BEB79B8AB56C78C1893FDB887F2E20C7C546628EF2D585166D1AC1335C701F54A21E85DF8FC48BD66D731AD157692FF3B2437E85F0D02 +ct = 69974372EF5FE414B5D02A8FD112EAC801D5027D712766690F3BE8DC7CF5408B80044818FA596CC7AAB1E871E3FD62736AE66514CB760169C001D6F185CD0080C14A1357B8E12036E6A1996255B4DE6D1AAE756FF3CFD6BFDBBF18C9D3459FF8CC3315AB90CB6C7DB0371E6BD001CCC8B2218BEE86F114B9904D3304A1F177DF0718765B6358C8BE7EDD961CBEA424DDFE38201AC5F78006F70EB7B57D2ACAD3AAC08F2F01E297D156EDA318A6C67AD5526938E5C183398DF76F91668A8BE64BF7C751904AFF99D00F9E071B2CFB4F5355E8B84B9E59E2781DE03D01FAF77C4108A3E7F6969CC09DEE6C0D54E1AA80A371C184AC93E0A852A56B3DCA6D24B31961B333355EC13D84CA0693B4CA2F55C4BFDB00B4F858092D63DBCBC6AFD38C6BCCDF967B2C039E58EB43ED0B347A887D44543583CDAB22DA3258466D0AB7AA1BFBB85520F75DF6B9DD01556D408B42F061FDA7EECBBA142DC6ED +ss = E8F99D5CFDF7D84DCFB663A77856D6B3 + +count = 72 +seed = 6960F21C7350DCF41B4770C551DC8692D8BA2C0B6E162C589166FF22E7A1AC0F94C2F48504A5F7EB0DA094DF427BC98A +pk = 302D79030A8F84399672BC554CEDF7FFC9B9B4953C04129C8245306FB787C2CA2F27322BB0EA1899A421E2376504F31E56B9E47A12C10028D4F8E6C9CB94F760AF65B7F5F86920F797F6B8A25062839C4BA0CDBD3B9266FD17FC10D52E6CA7F3390210F8943B0824CF9979BA410062DB8F749903071BF66A9FFD3F12FEBE6EC2F5774128E7FCE6D5A55BD4DA635A86C7C880996FA6570523FD17E509E5B1F53A4DE83BCC003E02C10AA4A89DE190EB56A08F4897E92BEE3F109EEA1823532207CBB84BF233A28E17D7766CDDE20140FA844DF518D58496BEF75FDA00F98F9C3948CDFA6FDC2572CE27C65609893996B9BC69E65DFBBA196C0404014E32C9C128EA2D37211C2AE344EDBE0AB9BD5F7205165501C698C8671A08F27E097BDB55784AA94DB80AF5966278270500DBAD9FAAF23989569DEB2845864D0EB7EA9F21315ACFA2F969920BA71D00 +sk = 1F7CFD2B70863154E8A69D1758532E864F68EC73C821458EA0462697A39E61A679CC5B069452780D4E890900302D79030A8F84399672BC554CEDF7FFC9B9B4953C04129C8245306FB787C2CA2F27322BB0EA1899A421E2376504F31E56B9E47A12C10028D4F8E6C9CB94F760AF65B7F5F86920F797F6B8A25062839C4BA0CDBD3B9266FD17FC10D52E6CA7F3390210F8943B0824CF9979BA410062DB8F749903071BF66A9FFD3F12FEBE6EC2F5774128E7FCE6D5A55BD4DA635A86C7C880996FA6570523FD17E509E5B1F53A4DE83BCC003E02C10AA4A89DE190EB56A08F4897E92BEE3F109EEA1823532207CBB84BF233A28E17D7766CDDE20140FA844DF518D58496BEF75FDA00F98F9C3948CDFA6FDC2572CE27C65609893996B9BC69E65DFBBA196C0404014E32C9C128EA2D37211C2AE344EDBE0AB9BD5F7205165501C698C8671A08F27E097BDB55784AA94DB80AF5966278270500DBAD9FAAF23989569DEB2845864D0EB7EA9F21315ACFA2F969920BA71D00 +ct = 700507E9C566CD975B5573B12841FFE0BD3C6FAB0819E32AF3597AC11FECDD32DC7E914F3051A464646ADB7DCD955406F8BD93A87A1D00198403AA55F866D4E2BE203AF19DD11C4979414067C1CC208564DD0F9F85D7C6D22CCD599C86763CAE36CEEFCE7241E7B7FBC75CA5F700D4B7A2057E032C6DDA0FD7ABC2D3ED92E972E0285D727A072E3906D74168FAF103CDB329181EE0680B0744FED177EF185D4EBAFFA4E80049ED569D9561E5007F31E8E32F4D0B621AD280138BCE99F5D918D7AF73D6E0F7BF9FF1D8700E7A4C9E1DB2D7E2F820FE24A120B413340150427DA3999440DADC95B04712F54EE28F20C430995C554AF5F94D477040AE31DBF6FCC86A4920D8EAAD1D1E192F52862FFDFBF2AB5D0021EC3976E7F3D364C629EF6B78DBFFE46B3A815FBE267B89771AFCB09AF1BF8B06D431BBDB32DAF1F3832DB8CB746D65628124DFB11A01EEDAC282384C9EB2278AC7109910846A +ss = 58FF3C071363D83AA6B6B330A6E48D5F + +count = 73 +seed = 53DF46012CAD4A745B7A3C06E18CA95E0B839FD8161E3025749A0887549EB0ED6A44EEEA08BD6060D6509DBF7E9DC864 +pk = 3BE5CA49D556D1110C266C6AA2630C76656730C67B0D221A25A53E68A61AF5E5E62F09E5A210FF63E6FC83AEE7067C0C5945A08EFC9D01C5BE185F968A156B1EB1F81550D7513415AF3B5CACA0E8550A3837C360E454BABEFD53079296302A86717BB495B464F70DF4F7BEC634002ADCFC680C347A16A65591944495BABBA684782C44DF252637DFC16B7C346E66BDEE8C53FFA952D25862865629209918ACEBE5FE846B0164BCF37149AFEAE222C7DC0B2DB657A365C936071055D52A19A1E20458AE94DAAA5B472423D9876D4598DEA7550F793F64E2F153F9CF018315A053742073D5E6E47BFC72155BD4DB566CBD60A6C3394B84EBE66A5552928C44CD34574D34F36B024807EC501BD8F115FF6B066101765AA098CBD6CB1627CB851573B153DA3E767E713C3960F1E034D4880F238E3D1F67D391863A8178FA51E41DB1DB73BEAACFD3E38DD701 +sk = 3A19577908EFD37697B8EDC7FDAF47D13F3B3F40BFADD4CA842C82D0220751A528282593412DC138376B14003BE5CA49D556D1110C266C6AA2630C76656730C67B0D221A25A53E68A61AF5E5E62F09E5A210FF63E6FC83AEE7067C0C5945A08EFC9D01C5BE185F968A156B1EB1F81550D7513415AF3B5CACA0E8550A3837C360E454BABEFD53079296302A86717BB495B464F70DF4F7BEC634002ADCFC680C347A16A65591944495BABBA684782C44DF252637DFC16B7C346E66BDEE8C53FFA952D25862865629209918ACEBE5FE846B0164BCF37149AFEAE222C7DC0B2DB657A365C936071055D52A19A1E20458AE94DAAA5B472423D9876D4598DEA7550F793F64E2F153F9CF018315A053742073D5E6E47BFC72155BD4DB566CBD60A6C3394B84EBE66A5552928C44CD34574D34F36B024807EC501BD8F115FF6B066101765AA098CBD6CB1627CB851573B153DA3E767E713C3960F1E034D4880F238E3D1F67D391863A8178FA51E41DB1DB73BEAACFD3E38DD701 +ct = 45B85520B276EEECB71AECADCB02674CD14D2D35108207C8053807291BE2443BC5BF59566F582007BFBC418987C6685C4587E7AB984F00905136A595DEC7B9A70BF8A34D84D924D1C14B5FC4706C0DE7A1B886A8A6F9E100F8BFD1924F581F0250CFF6CA33139F8DFA9ED2BAEF01BA369656EDBBDADF489860DD6AF421DC7C2DE8C94B5B35F2AAB071496EB4C30B091830B40FB599C9E6494C776299D2696DB123B21024023D518CF99CD614D4F44DD730263AA9D9245F1A7793C75E4B7FF3E71F96D85A02EE2CAD361A3873A2E0A40F1C1E9043A03DD9D475946301E88930E226CAAAFE8D84FE49DC70A6EC9839ACEC4CD315417F05C2807404F98A0E6B4ED1F6B707C0B9035ECB2E0965AA15C1CEC22C010213B5252C33586DBC66EEC7EBB83B849EC9A46D2C48E52F78C24B0E3F9D00D380D4C0AF1ACBCD7F7582AF5F76EBC58FDB75271840EE07017D0D7275AAB4062C0C8FA446ABA19191 +ss = A4E753CE52D682D4BD468D9BD872A6D8 + +count = 74 +seed = DEB963F8B1D8FBDF499D564BA8D2D47915BB402DA02F17031B37B4039A842AFB9B7E48F37200605992BD2429427A7A4E +pk = BFDF47DD1581700F7A19EA3554BAE3E7B985962418824B33422AFCE02D1B4A27373F02F1D388C87CE3ADAB3A39653659ED6FB9510A0D01C7A54616C86DCF44CD213345D439D537A66AF0860C5B2A32DAF3C7618DDA061B7351FC719A7F6754BEF63B083A8B565FEB136BA801E100F08D5E89B8D14CA0E8B06507CB4230ACBD0C4D2F3EBC32C9BF5CD873A3E353A3EBAC565677C4A851C2E907E27E76A27B62DFA9A46EDF0070821563BCAFB597F631D776DFB2F5591C3D9CC2AF8A0A06F347D3F7219E9FDC527A5A79FC7C3A2025E9C42C0668AD75C0B2B561F21701BD4993AB6EADC93FA9216812B7E7521C69D3062F89036EDDCCAD2D23F5B158C54F2E74AD1B1FFEF763ED902D3B793A8A21A4F1040963010F73C9C8F42C6B76E41D6982566AFD76B03F48AFAF4228453CF3CA2C754FC9C92DEC9FF93DA36D32ECFD1587B9E448046EC883AF648500 +sk = AE0F65E29F38804A6759F70F4D01E2AAA1E0F79A8C218EB9E2D0664BBD9F1E531A366BD8CAB1172AA6A64600BFDF47DD1581700F7A19EA3554BAE3E7B985962418824B33422AFCE02D1B4A27373F02F1D388C87CE3ADAB3A39653659ED6FB9510A0D01C7A54616C86DCF44CD213345D439D537A66AF0860C5B2A32DAF3C7618DDA061B7351FC719A7F6754BEF63B083A8B565FEB136BA801E100F08D5E89B8D14CA0E8B06507CB4230ACBD0C4D2F3EBC32C9BF5CD873A3E353A3EBAC565677C4A851C2E907E27E76A27B62DFA9A46EDF0070821563BCAFB597F631D776DFB2F5591C3D9CC2AF8A0A06F347D3F7219E9FDC527A5A79FC7C3A2025E9C42C0668AD75C0B2B561F21701BD4993AB6EADC93FA9216812B7E7521C69D3062F89036EDDCCAD2D23F5B158C54F2E74AD1B1FFEF763ED902D3B793A8A21A4F1040963010F73C9C8F42C6B76E41D6982566AFD76B03F48AFAF4228453CF3CA2C754FC9C92DEC9FF93DA36D32ECFD1587B9E448046EC883AF648500 +ct = 8069BB2B0DC833C4A359E1F31AAF513AA4A26826CC9EF2F1C5EED50A8C44994B4DF322724BD8D35375D1EE7018DAD3A44C051B92950C00F56634BD3EF14EB2D4603EE3F72B47BA9ED688F3A4C99D21A3C52EE18EA6032EE07F514D6FE1C462FFD1ABC3628CB52866D536E6D47400EF4B861FB3621714923FB1995C1C072B2121DEF1109E995C97482B009CBCED8FAB14DD572F5261C717EBD6C2BCFE245AB2B669FDD0B70166C3EFD6D1DC97DE7CD63AA125D4816CF4B7CE2B2D19EE6BC0FD1A5F7F0B432EBF77FEAE12DA413A4E594C550471677C0F2E80F913C9003127CF2850AB91ACD60269B9CFBD3051FBE4783E682D014F71E040DE213459C052E5EFD1EB377D8EF89CFF2C8CC5AD7C1EBFC25F4D850129E3AEB6999E9592AD4B467DAB3CE8C8DECA783D1B8133E3BDBA5667EBB7205563DB0B770F68565FBB9E5E14E63E6232B89EDFF8B77E0086CD2DABE1865962834D4C51E3D64D7D +ss = D229BBB3CA9080B96B26D87F2FBFCC26 + +count = 75 +seed = 8E2995F1B3E43853B18916BB1212ACEB05898E2B177A87ABEB928AD7184E59695C56B2CCCF5DB80853C28A525E327D13 +pk = 642C64398DEDD29CFF26006A5C989C9114FE2CF5D2E5DB45A1DB66A42C13DBD08EFD116CDC3092271A78BF5D80197921ECE35537A3770109AC49BFDC73254DEC64BEFD4D326002293FE8C5177E3CA648E8ACF9D3A3A1B576EE40187A68CAD01DF11E337455860377318097B861002B3E1A7E06D7BC8A11BBEA50419EF432DF8946A62DAB52D04C01FCD01EAB2CCF798D0E3B4625CB8A06F853A0B3716243606B6C871ED800B13DDFC1196E65C2065E7EA3E70B450D82551A52F2F848CEF9DC41F9BBAF2C5A9345C3EF4E915B43FE4C8E4883D403D420AC4F19ADC7008C944732181E48C3650AFAC2A6BD47815CD0891FCBCC5ADCA9BC0CD788998F947D11880CADFE1FD458DE4218C5837D07DEB0E989C1E001A9F281283F8273BB0CDB912F54066F13A3A73E65691BE0CFFE719C0C556BD2BA770484278E91B9E4FA76BE271DB91A7939CF48CC54ED01 +sk = 6084A235F79DD093EF6D185B54E69DF3F1B7A24CB6E6F21B112C4AD8FF7CE8A9BDA1BA1751496BF39A354B00642C64398DEDD29CFF26006A5C989C9114FE2CF5D2E5DB45A1DB66A42C13DBD08EFD116CDC3092271A78BF5D80197921ECE35537A3770109AC49BFDC73254DEC64BEFD4D326002293FE8C5177E3CA648E8ACF9D3A3A1B576EE40187A68CAD01DF11E337455860377318097B861002B3E1A7E06D7BC8A11BBEA50419EF432DF8946A62DAB52D04C01FCD01EAB2CCF798D0E3B4625CB8A06F853A0B3716243606B6C871ED800B13DDFC1196E65C2065E7EA3E70B450D82551A52F2F848CEF9DC41F9BBAF2C5A9345C3EF4E915B43FE4C8E4883D403D420AC4F19ADC7008C944732181E48C3650AFAC2A6BD47815CD0891FCBCC5ADCA9BC0CD788998F947D11880CADFE1FD458DE4218C5837D07DEB0E989C1E001A9F281283F8273BB0CDB912F54066F13A3A73E65691BE0CFFE719C0C556BD2BA770484278E91B9E4FA76BE271DB91A7939CF48CC54ED01 +ct = 211EC0A98ECFA99BCF11E20042BBC5AC8EE0529BE358D76CD0E35FA55597FE8B27EBC856B13328D88F4D50D6BA169C821153417186A701F8038354A03885D7EA9F65A8CCA89316C29B5CF5EC4820A79E1A745DC32C81837675151862909DAAE94D6B71F444E507CBCC540F8E4200F59D56AF1EACCD8B97A00B084748A066FE2FD945C7A69F07E7EFBDB1CC947C7BABAFD95084405F60A9741C40D8AA7F9120619501F81400C381CEA185617FF07832A0C9A79C62E41D80FB89354AA20229C1B346F4B5B8B127A991BA2E430E7FE29C4B99F9BDAFD77581607BCC0E003EAEDE18AA0297590E2E27F4FEEF0FFBD15C31BF6D1615FEF8CF15533671FBAF71D2760DF9232327A27A47E08227B295374DB0F25C9A01E70998C6E54D1AA70D5867F0E1868D27A85CEE9055B270BFE04973D4B29F14AB8B0BE5CB2BE9D2A4204717AA4063721C26AD72ED6B2F007E327EFFDC4A5FDC9033903FC5D8681D +ss = C96B986298CC6BFDA4253200192D1573 + +count = 76 +seed = 9218943C51FD2DE47E509AAC67EFF176795102F37D7A2017E3AFD768FCDA7877AF38739B00FCDF227C2FD62EB635942C +pk = 26297E9605B8847A59C1479CF45C7B4DE51CC85E6F2D86C561D43B7BFEA88AB65C2F52E854EB95D0693D536BE960307BA02C216A33C1015E39F12C35F7A15AA6D7BE547F28599A4CEE951018A8801EAB191DAD1B0EB24E6901C10E14A000791BCBC61519AB12CA5C22701A1B6401484E47B3B1D27F0226616E7F5CE4C166DF11E3EB76B328181215FC6E413985D23D7760BBAA2A55857AD6A33CC61E58B17325E599367F015FB6C73EEE26DBDEAA051A17A323EF6768A969CAC8D57FCCCBB396D626F7DBD01A6EF939E2D1B42EC5E03E638661677A69F4343EAD7B01CEC04B8E472F3DFDA39A3E5487E972B38CD380447CEFD39DD0E89EC316EFFADA55B6FC8F15334E2755587F44B4CB34DB6F91585C66F1007A6D027148DB73CA52CA86086C342941257A99B67F485A1B7D40AE65F512C5FB43A517C9E7D073954F6B70377EC02AC49B23F22E0DFD00 +sk = ACD1C0217FAD5CAA4235544DD9DE153AD8BB1AC46327E9F25BF1784AA724B0126D173A8D3445F069FA2C7B0026297E9605B8847A59C1479CF45C7B4DE51CC85E6F2D86C561D43B7BFEA88AB65C2F52E854EB95D0693D536BE960307BA02C216A33C1015E39F12C35F7A15AA6D7BE547F28599A4CEE951018A8801EAB191DAD1B0EB24E6901C10E14A000791BCBC61519AB12CA5C22701A1B6401484E47B3B1D27F0226616E7F5CE4C166DF11E3EB76B328181215FC6E413985D23D7760BBAA2A55857AD6A33CC61E58B17325E599367F015FB6C73EEE26DBDEAA051A17A323EF6768A969CAC8D57FCCCBB396D626F7DBD01A6EF939E2D1B42EC5E03E638661677A69F4343EAD7B01CEC04B8E472F3DFDA39A3E5487E972B38CD380447CEFD39DD0E89EC316EFFADA55B6FC8F15334E2755587F44B4CB34DB6F91585C66F1007A6D027148DB73CA52CA86086C342941257A99B67F485A1B7D40AE65F512C5FB43A517C9E7D073954F6B70377EC02AC49B23F22E0DFD00 +ct = 0C24341686DB351AE2ED452C4457AD1BF175D450C49070720894B7F70DF06F5875FC667B1B8C394EFFA7D19DA7D74BAA7CEF335E367201109F7671ED81D537A69F4F1CAEFFFE70228B98DF2740C071E5FF2C2D632CEA43EBFCA60B58C04EC6DCA7B4F33730C83E9B3DD638099D0036CCC8DC106FBE1DDDBBF26A1737E826903C9A24DFC985756F264BFEA891F50F074C877D4C6F2EBBFB422DC22A5299FE07A3554AB0E8012BF4828E2EA61B9C8219E1B8DFF8DB95CA3C981B0B64545341427A34937001E70E7F6A9B6D2791CDCCDB3B343DE8CE1E0A449B3C12F201CDDDE7D9A63E1783B69F7969C1DE25FE1EE2AAB4EE950CF6F80F1323A2742997C353F500AA45ECC5EB18C392CBBED14F611A2556E78600785FAB246A64C1D7A6F2C31FEBDA748DB0566B1CABDC8ED18C14CD621A5F48A9651674E15CB64A1EE6E87E36BEECC6577FDA0C068F38008BC2009E582D2A52D1A8842373356BEE +ss = B1466D6C93EDFD9DDA1805592F90690D + +count = 77 +seed = 542E20078ADD5296050AF150360F057F6B9AB3BA835589DD56987DE805F900B906505B5390A0D86CBA28038992DFC59A +pk = D5BFE0A0BC5D1E06ABEB2A65F7B1B24093F5F9DCE46F194EDA944F44386AB427832AD4A37BCB10ACF082FB9DE250CA206B903412FD9301F4A4F756824FAAD608C0EFDBFC92AF40CA11B7D820752165CBE49EC964DA9574FD16D430F641E6DEEE62DD74B6B3E44C315940CA420B0108C38CE04E9EF520F2682A8D8E269F13C0C11E9B630B1CC812EBFAF28EB12416480B90BEC755DB430CB63CA6FBEE259D5B078841131F01A3261C4B2D737C7BC6584547006E40D8F8BD47698E403CD13CEA2E6A30B73442BF34CC08A2DBCC5DF1760A8ED4FC376BF9F761FE6BCE01F52DF1EC7AB307132EAADD05B6F331130CA2C56F38E1441CA4506794768DEACD84F075B88176061B318697490AEE4EBF3B3D3C8523AA00A8002DADA2CC3BF8FB0AFDA93EF74CC1336234180E86A615CE1FF92E1DD2ACF183613B37BB5484E9CC3728B89036A4A976652ABDEF2302 +sk = 241191401A63AFA750F05662E354DDDB30AC637A035D3B650C62A021078AD7F1E9E3D14FDD4B7FAD20DE4F01D5BFE0A0BC5D1E06ABEB2A65F7B1B24093F5F9DCE46F194EDA944F44386AB427832AD4A37BCB10ACF082FB9DE250CA206B903412FD9301F4A4F756824FAAD608C0EFDBFC92AF40CA11B7D820752165CBE49EC964DA9574FD16D430F641E6DEEE62DD74B6B3E44C315940CA420B0108C38CE04E9EF520F2682A8D8E269F13C0C11E9B630B1CC812EBFAF28EB12416480B90BEC755DB430CB63CA6FBEE259D5B078841131F01A3261C4B2D737C7BC6584547006E40D8F8BD47698E403CD13CEA2E6A30B73442BF34CC08A2DBCC5DF1760A8ED4FC376BF9F761FE6BCE01F52DF1EC7AB307132EAADD05B6F331130CA2C56F38E1441CA4506794768DEACD84F075B88176061B318697490AEE4EBF3B3D3C8523AA00A8002DADA2CC3BF8FB0AFDA93EF74CC1336234180E86A615CE1FF92E1DD2ACF183613B37BB5484E9CC3728B89036A4A976652ABDEF2302 +ct = F7B3FADEFE141BF309B476DFC9E621AAD059F8A0902C5217D8923E2F60655C87BCBCA4E49366F95A1C28A40D42C9238C2D0FCF30FCE301EEA357DE19D698CE5DDCF4152F9FE766FAFD0A4F6A8C1DE63F33A810F08C7FA39863EE8A35B1634ECA054C78AA961532E9C1D9C3D98E005EF456E603B246FE280DD5069A6CA40353F318A453E51E4BA3905096401E3AA9750228BBA806C98762D8AE5E4C98859D97A2FAAF97790174125CB37420224A8CB0E025D4BD55B93DE058769EA1CF436B1401660481DAC65049F25014671BDA6138C3F56EBA6235D75DB58C0A0D01EF2240227274D3ED866D0471C000C05F177587203F60CDCE413417EE7934A166D45C104469B031E292376253EC892230EF620E28A3F3005559C9D7D7735865ABF7041DA0180FD60493B6DF3E3463590B5FE02CB278D566144DF82838A5564C97948C8E66C245995B1EFBC7402A013F525D7D6262291C6CE4F1EED0904E8B +ss = 437B7246BE78180BA44324C3B743A028 + +count = 78 +seed = 6A85A61DD08C0733FCBC158ABB49FE0B0D96A50DCCA140A2E9F5A254F1901985844613B1C656C0CB0112620591B88AD0 +pk = DF14F17DE9364D2E04391D6412671ABF06A75DC4E280FE366D76F93F43E7D2B60059C4CE42F2C0C8E0D2EC2B876802A2D84E1E826D7000C90C03F404166DD5C02703216F53E4E108FE9CFC889E44F6ECD90CABA745B81A563342C56B45448DF77710FC89C1D3F66954F2D2F359015B120886BD0F88CCE40FAA4805D63FAB0F60A72CCBD187A0DAC23286DE58B09D80128D8ABC6CEDACAAEA2F2197EDEA5B44ECF75973490066E92A64F2857D83CC1A392971FB16470E5D20AA492E9CACAE88DDF321C8EC0995BBE52AD0688ED2957658930A27C43148F21A1EC01C02AF3DC6B958D074FC26B5F36392465BBB3C8276EB418DAF9F7C74CA00EA53A5F62631C7DDD72CD62999DC305E89A7D709958ECCB2D9DD014E31A053749C86B2658429CC0A89294DB18EB401C29AB7443F0E9153F47EF28A32D73BF4DDBC1FE494216CB40631C645AFFCA672F14F01 +sk = B9A6B0C05677E957D41A34BA03BD06F2AA88CD55413EBE82AACBFF9925A16A40931912C860D5F334F236F400DF14F17DE9364D2E04391D6412671ABF06A75DC4E280FE366D76F93F43E7D2B60059C4CE42F2C0C8E0D2EC2B876802A2D84E1E826D7000C90C03F404166DD5C02703216F53E4E108FE9CFC889E44F6ECD90CABA745B81A563342C56B45448DF77710FC89C1D3F66954F2D2F359015B120886BD0F88CCE40FAA4805D63FAB0F60A72CCBD187A0DAC23286DE58B09D80128D8ABC6CEDACAAEA2F2197EDEA5B44ECF75973490066E92A64F2857D83CC1A392971FB16470E5D20AA492E9CACAE88DDF321C8EC0995BBE52AD0688ED2957658930A27C43148F21A1EC01C02AF3DC6B958D074FC26B5F36392465BBB3C8276EB418DAF9F7C74CA00EA53A5F62631C7DDD72CD62999DC305E89A7D709958ECCB2D9DD014E31A053749C86B2658429CC0A89294DB18EB401C29AB7443F0E9153F47EF28A32D73BF4DDBC1FE494216CB40631C645AFFCA672F14F01 +ct = 1DCD103E5C2F11A2ABE82284B694FF926EF59277450305849E0E21FE41978BC1C80E2530B44ADA96A3A78CEF861FF505AA279900045D0198C1EA37E0C8D56724DC4D23836D5D2E2275B6383231A834B51B22A0A0645E11F660FC935B2FCDA5172B249AFA1B1C2A44A75AA5429201EFF31FB2522CED0E539D1AA474E0564260A28EA8A59B0D21088AF25FA35F024E0A21ABAE187940CEF6269F3275B9DB80D7C83139F94C01E1C57687EED12C1E4530AF7B636B7C1C5DB85419FEEB675AF13335E1272352B4A207AD17976B1B396ED4408ABDA935F5114454300AC30135F6B6B8682DEC4374561F85D18C2175F8FDC4945698A89BEC32A5D6D251137AF94628ADF66065D04C875B24C2C158384B52249A07710168D83E4B7BA942625A9F279B22C9A7EECBC04947FA9FF88BDDF3C6432BE56E71F1CB7BB643A4D314C7C78CEB6C10B7D47CF67612B5030137E33087221674FF242B2441EA0E31D8 +ss = A7CC77ABAC122AE68F6D5F9BC4A01AD1 + +count = 79 +seed = 7F4A56EDA151E7B097CFB8EF980440FFF707AFFBA91867C89522CED6C5FF3BD7F5F00BB49DDD615D9361A7E4EFA42851 +pk = 3F0DFDEFE400120A9557199CEB8A8FF36675D04B70A1C5B677BFB1D8FE1220E8AEAFDB3B48A91CEDE5E015EDD661CFC8F1BF0492C129029A68BD556471F971D84D2F031C24618CCAB69C986193DEA9C026CB4A5CD371D7E92C8297385BB7C2FF95EF3B98FF89F316C5D1B1272F0219A7CBBCA980BDD23C4FAB892437F1E2F73326CDC53E08A8EB1C10670322B32672BFD4942F7341A9371FE09972CB8ACA269BC473B47A00D83CD1FFADC54946A033F99DD7C188340B5339C97AB12221130CA0C57ED26215255405F882E1387B14DE764024E42DB70E7274798C7700297420196C348CE0646AA9E17189CF99E0429B469E14C41FE0280B4452C08E1CDAF2A754F45602230573586DFEB527FEEF06C7CBAFA6006B218A5D634054162F01BA46B2708BC898FB6BAEDFF6057BB3DC7922ECE7B41551EBFDAE0046EEE572D33DA00E4CED015A6E4A72AB2602 +sk = 28A96C71577BA00C94F99FE965BC595AED4441D5BA51EB259B0F084AE277B0CF1315E715F919D851482AF4013F0DFDEFE400120A9557199CEB8A8FF36675D04B70A1C5B677BFB1D8FE1220E8AEAFDB3B48A91CEDE5E015EDD661CFC8F1BF0492C129029A68BD556471F971D84D2F031C24618CCAB69C986193DEA9C026CB4A5CD371D7E92C8297385BB7C2FF95EF3B98FF89F316C5D1B1272F0219A7CBBCA980BDD23C4FAB892437F1E2F73326CDC53E08A8EB1C10670322B32672BFD4942F7341A9371FE09972CB8ACA269BC473B47A00D83CD1FFADC54946A033F99DD7C188340B5339C97AB12221130CA0C57ED26215255405F882E1387B14DE764024E42DB70E7274798C7700297420196C348CE0646AA9E17189CF99E0429B469E14C41FE0280B4452C08E1CDAF2A754F45602230573586DFEB527FEEF06C7CBAFA6006B218A5D634054162F01BA46B2708BC898FB6BAEDFF6057BB3DC7922ECE7B41551EBFDAE0046EEE572D33DA00E4CED015A6E4A72AB2602 +ct = FC98277A808FD81DDB8224E78835D0D276C84EE80FB587F473652DCBB1B2A7EFB759D6DF3B725F3EDDBC247716D8CCA07337D3BE366E017890D0C02ECDDEFB5F6E1F7542FC877E381D8159847BA70B57469DFD3FFCFE48D408424BE69D75E657971BF736AF83E57CCA883B910200D606AEED67BFBA5570A32AE41B2CE4204C2F5970D4CEB3BF64DD7ABDE6758770D2B038BBCF02AE3845C43B907E61B9563C88EDDD069A01B27544F06A558FB2463124A9B5A94C52B664BD8ACB15A7BC02A60515995459D5F07FA1E4C2CC9504E0E766DF020781970E3237FB6872019F02C5F5D86B0A05E3C97DCA8D6E8513F9D8FC3D57EEB3ED4C6F5A26895DE5BF0C23E392E24B9FB4E2BB825F83FFB1402F0E4AF48D0902E0E3350216C5D03A6D4674AE99FF58C2B373ED44C788475E70A435C5DC83A1B1F548441761B9489AE91798674117435C3438A3E62312010F58A35703F1A7A42FD7383FC464B6D7 +ss = 1668F6FE2A022440D748D2225256D97D + +count = 80 +seed = 09FC004519BCF85B20D25D314A0DFC79E00CB6262A7DDDF9C52473641AFB8CFA0F5DD5F53558184CAAE9EC34B459E98E +pk = 24410A206CB562AA5CEB0B04519E66B380BECE417D9D6EC10AA2076645DB2BFBA5183A715074108A5406B75AA00725EC81591397301902973AEA8F1D532AEE77B78B5F0BC3CE8EB553C7C7D5D0708B1565E50A67E1E5B5DB34DA089214265F6E2F79D8C877C5065AB0EFF833D6005E002FF7D30880AD3BA795D27B678D69C51043AB38254DA0B9076380DBB21C76F104E4B0DB9C316FAE0AD2F77D8C96DDF1552394BBDF00262BEA8C1F9C1E6F8D468032E9E087AEABD1E7AD904BF0AE15F6598CA1A236B555F1C52FEBBB79CD9AAD12DF1778AC75B5A0CD93E532016F4DCF0A633CCF05B551193029D057018DB12BE465F6683B17E61FE15A1FC7E0D49DEE3AE631D608A62E70BCA3614C336CE8F2D83EE100B816487C5532C8FC8BFA0FF6F648F530EA50040394EEF8F32B89E9010A8B11248691871B6FEB8F2681B10151775507553FD3F65045CF01 +sk = C08BA2EF8C3A0A043AFAD931652D7A191572E7169D50969A767734B15CBCAA4ADA2CF96962955342CD54F70124410A206CB562AA5CEB0B04519E66B380BECE417D9D6EC10AA2076645DB2BFBA5183A715074108A5406B75AA00725EC81591397301902973AEA8F1D532AEE77B78B5F0BC3CE8EB553C7C7D5D0708B1565E50A67E1E5B5DB34DA089214265F6E2F79D8C877C5065AB0EFF833D6005E002FF7D30880AD3BA795D27B678D69C51043AB38254DA0B9076380DBB21C76F104E4B0DB9C316FAE0AD2F77D8C96DDF1552394BBDF00262BEA8C1F9C1E6F8D468032E9E087AEABD1E7AD904BF0AE15F6598CA1A236B555F1C52FEBBB79CD9AAD12DF1778AC75B5A0CD93E532016F4DCF0A633CCF05B551193029D057018DB12BE465F6683B17E61FE15A1FC7E0D49DEE3AE631D608A62E70BCA3614C336CE8F2D83EE100B816487C5532C8FC8BFA0FF6F648F530EA50040394EEF8F32B89E9010A8B11248691871B6FEB8F2681B10151775507553FD3F65045CF01 +ct = F47AC313CA6775862787DC223D09F375E6DFEC29F8CA0D2D212A1E544EE8968EAD4CF488E832D2B1187FEC96939B3186AA37BA3B8746005BDB92A4562BFCCAD8598479FE32F68C530ACD648727EED50DCC9E12F0A801C9239E3567E392296A986D61FB4FC307F0C3DDD2D9715E01DC7D41FF0E895709527F905579492925C2E11E5A1D350F433CFA40781B50AFCCF0E1829069DF081E13C03B41C97EE5C4CF6AEBA88D6C0119AB0B070737D70BAF4255319A644E47352DB4DB57E96AFA633C0F16949A09B6813BBEDDC869EC43294D393E8CD61E840489095134160040E2BF606D9DECDB41C917FE455924B760383CDA89BDB7A380C926BEEE84187D85B0E8B779D65740601CE6202BE0B03D43BC9F71E63202FFE6F9036A55C5A25C58D78EA402420EE957902C3A0C760791F94850AAD409BBB4BFFC41553A6451FB13E9D1594EEF2128A1B138783600C7058B784C0CEF3B581F5E997C3867FD +ss = 8C09C3984055F2706130AE9F5291B941 + +count = 81 +seed = E3C41CCA6F04CFE7732FD54DE30CC5CAAC93E2F80E76AED7D24A962A3969C1B6A311459A3EC3E510E3E9B1E4291D4D7D +pk = E763483C849CF162B8B7EFB8C0AAD1FD8430CB09B8B9358D2874819C50ED045A3E7A1F67096161F37A5559BC48BCAFDBBC1AFFE7480901AAB866BB717B4DEE853BAA07CE2F0E56EA510D09514E1102B2E05B3F7059803032EFD941BD494ED97D36053AA51D3BAC6731C6857A94003FAFBF92D70578D25071625F0B0111CA1A21E1236A671CDBABF023297796D8089E740C05608B3F5BE5C3C462FB52902D73735EA3872F023A22D7AB2324C2D12E3356ED61A21C02FB245BFE5E62BFAE46387448A7294FDB54ECF7922E21299C4C2F170718458428E0A2C21B772102D236FB733788DCDEE112CF533BF8528E5D5BD41167BFA8C79E4CCB26B4C9CACCD5534324CE7953DB4DC994D79856D9B46DF7AE2F61C90154997BF205796F86E9F52980E8D73BA371FB9B9C85C6E35A6E7706C1C11A6AE4FC1DABAF4B28E2BB2D0F50687AC8F85721619D5ABFDC00 +sk = 0E3B30E102D707538C2671060F603BB009BF978E2A6175A868F93CE4969C69204C0D234AA7285DB4E55CEB01E763483C849CF162B8B7EFB8C0AAD1FD8430CB09B8B9358D2874819C50ED045A3E7A1F67096161F37A5559BC48BCAFDBBC1AFFE7480901AAB866BB717B4DEE853BAA07CE2F0E56EA510D09514E1102B2E05B3F7059803032EFD941BD494ED97D36053AA51D3BAC6731C6857A94003FAFBF92D70578D25071625F0B0111CA1A21E1236A671CDBABF023297796D8089E740C05608B3F5BE5C3C462FB52902D73735EA3872F023A22D7AB2324C2D12E3356ED61A21C02FB245BFE5E62BFAE46387448A7294FDB54ECF7922E21299C4C2F170718458428E0A2C21B772102D236FB733788DCDEE112CF533BF8528E5D5BD41167BFA8C79E4CCB26B4C9CACCD5534324CE7953DB4DC994D79856D9B46DF7AE2F61C90154997BF205796F86E9F52980E8D73BA371FB9B9C85C6E35A6E7706C1C11A6AE4FC1DABAF4B28E2BB2D0F50687AC8F85721619D5ABFDC00 +ct = EF5471DC00603F3B6CA49A046394E8E4550180C5086A4EC4AE524683AB05DC43B9805F05610F57E29D7A4217A23967A7B1FA471BAEEB009200D3F880C9B7C37634F397AB6263AAD865B527C6779ADA27A6442079C6947F43BB7DDA8F230E532F91F9AF6B50C7B939D56435FE51015BB618EFFB9B0210A020809C9308A05CF82D33FF23FEAA00605D579D3B01BD28FBA1ACFEDA23E464F624B00A63E95D07900EF55FFACC013731F45F0A4BF688D09B85300A3FA142C7D060FCB477D0C7A84948882798C1C1082A397149845F6FD23D2E1CDABD6FF6B1B0A9E9BF4C009D8FE85E8347B6ABBA433F7C753B070C705C4C9C18BCB6B256746B4C755F6CC9E6A3D5C3738C93E21211D2402830A32338F617F376DA00656A023643417677B908FB426ADB37849BDD485C40554A52A7295534DEFEE1A415EFF291BBD0B2F0213DCD4CD63E7FD8FA449D8F52FF008C65D2F9E301826E9716DB1AE09B09C8 +ss = 657A6670077450DF16010E2B27552FF6 + +count = 82 +seed = 373FDDE922CFC416ED96B444E445BDD0962E8989F6C50ADF9912A89937C57217D3600B06C95440448E3F601AE69CA5BE +pk = 403E0FE2E4768D8AABA88A13D1095F6919CD6378D19B0E07564A839A2E56CA7DE01F393AA50AA8BD69D78CE8207A7A429B7FEC318D42001257C6378A904A283769B5D17A3F6DCB7B2248266002A5B00AF91B21B06A90A0FFA206AB41B14519D37A5A42A5EF98C3DBFFC9DF73DA00AA8F3EC93698526F004836C97DA5AD2C31B23C5D2246EF4907D9BDA97C9BD43EA08C5AE939F92524E6BFFC573F65006EE4314BD950F30084DE631F2AC3834BD6091E96AD30963EE8F1183B50BA51E416E33CA724FD0475E8343E1D83C8A69A6E6C5D01DFDE1B63228B22DBEEA30110D4B6A1F2708AC6397FEB87A82F8AC4497B144BDE41B15C65DD5B83D47594F0B10385C48A941F5890CE4B9A7CD3C6D463DCCA7D277B01956BBCF7F6944FD80527A65E63E56F4238E31B0EC2134CE28C603BC7E252792C37233316BA8D5D6DEE9EEA54AE421B5D5E9941FC308F01 +sk = 2478F7D3DE6041E7E5CD11C5E2EF483DB02E23D880594683E501A9F67E5885D5EFAB28CA726C65DD9C3E5100403E0FE2E4768D8AABA88A13D1095F6919CD6378D19B0E07564A839A2E56CA7DE01F393AA50AA8BD69D78CE8207A7A429B7FEC318D42001257C6378A904A283769B5D17A3F6DCB7B2248266002A5B00AF91B21B06A90A0FFA206AB41B14519D37A5A42A5EF98C3DBFFC9DF73DA00AA8F3EC93698526F004836C97DA5AD2C31B23C5D2246EF4907D9BDA97C9BD43EA08C5AE939F92524E6BFFC573F65006EE4314BD950F30084DE631F2AC3834BD6091E96AD30963EE8F1183B50BA51E416E33CA724FD0475E8343E1D83C8A69A6E6C5D01DFDE1B63228B22DBEEA30110D4B6A1F2708AC6397FEB87A82F8AC4497B144BDE41B15C65DD5B83D47594F0B10385C48A941F5890CE4B9A7CD3C6D463DCCA7D277B01956BBCF7F6944FD80527A65E63E56F4238E31B0EC2134CE28C603BC7E252792C37233316BA8D5D6DEE9EEA54AE421B5D5E9941FC308F01 +ct = ADA6439834C7BCAC8F61B4DBAFFD4EBC116196FDE0BEEC1F216D52AADAB44E967692B0CC5D6593B3A02A501F3415679A3D1C4D128DB500169EDA624EA81F0B9B31B320D135ED13BCE80B4320EB66DCFBF76D7C45C3506151A256475B4105B17B276AB35DBA3E6BD5FC8B54BF98005FFD6C4CA4C714914D29708DE71C948B235C6C66613CF86B8D6666283E78584D8FC7A1A332A82E2C17DCD09B65255BC7412D1ACCB36D01A539FE37FAA72432674A2B62AC63FFBCE68DD364F5F25CDFAA3B842966EB09992BB096241BB7924D180F11535709CB2BBC7EE4B8C98301ACF3E0AF53D3B8CA222C703279EB719FF3580E1033041B5474EA9D6753A0237BBE446E75FFF86F62F0FD7594B43D3E0CCA22889D669301CB1AE3593669DC516480F11192B23F6644E1AA106AC98B976AF3743A9FFD3C52402725061F87F9D14D01800E08BBC7AD3DB8B7AC312F0204D0A5BFD970CD7D90A6E388798D92FD +ss = F83EC12EBE74AD7A567E22537E605B62 + +count = 83 +seed = 16BEF67F7AC3A755C59C816478B75FCC16CE5844DB537791ACCD1EBD49D2824B105FD2E970F728C8F0CF16E439A9AE2F +pk = AFFF8BF1695CED245FBC2C8C7703DD13E4F9D052A689B35E6B8D2CD9D73622D3209A223D04A960A970DADFB62BD5CA4897244E28E3A500A659DE76B433D2884743E23C766442266C5E9C3F74A027684715D0A67A6A543742833272AD82D9AC992D94671A548EEE12676FD1129A0190D7C89011A8A0AB34F30D91FCE9B9EBE8B252F7A6513A3AC1A8DFC08044D91D396F812A25BB08867F39BF302F91FD1EB041A1A3F8BA018A5F3A9609CAF8B2A6BB64C9E37F22CCFA4E684B3CCE3187EA875E7CFC8CC1F14F0ADD1A5BCC4A4132F90FF1706333014B793AC646DA00A364EB3C317A0A396332006350C2BCA1F7BF67BAB73A7E4D702A1A685A4A1499B558A609FEDB159606394E492A283D43AF45765AC08B010502829B342612A91D46773F3DE2E25C615A7F2E3B2DD25721AA1CBE573AD4771403DF1097137356895C91FE0043EF7C8A86D95F0F3200 +sk = 9D405D3EBDAF35FA8722DE431B669722721A91D8DF95B05F40CC35754625090284AD6C131427DE79BAEE2801AFFF8BF1695CED245FBC2C8C7703DD13E4F9D052A689B35E6B8D2CD9D73622D3209A223D04A960A970DADFB62BD5CA4897244E28E3A500A659DE76B433D2884743E23C766442266C5E9C3F74A027684715D0A67A6A543742833272AD82D9AC992D94671A548EEE12676FD1129A0190D7C89011A8A0AB34F30D91FCE9B9EBE8B252F7A6513A3AC1A8DFC08044D91D396F812A25BB08867F39BF302F91FD1EB041A1A3F8BA018A5F3A9609CAF8B2A6BB64C9E37F22CCFA4E684B3CCE3187EA875E7CFC8CC1F14F0ADD1A5BCC4A4132F90FF1706333014B793AC646DA00A364EB3C317A0A396332006350C2BCA1F7BF67BAB73A7E4D702A1A685A4A1499B558A609FEDB159606394E492A283D43AF45765AC08B010502829B342612A91D46773F3DE2E25C615A7F2E3B2DD25721AA1CBE573AD4771403DF1097137356895C91FE0043EF7C8A86D95F0F3200 +ct = F692C2E446B8DE4E601A7F9C508FFEB376A2605C1060FEACD26CC1DA8ACA539C05ADF973E7596E9F58BEBA1BC93994E8D2C2FD50381D01F66897236675240FD1B781E95EE0AC81191725EEF73AB54C15056204D87069A90F179150B70D8C0AF9AAC73B1CED9A328F48C608FE7000D6D5499A365DC84727F87677AF22DA40E0A14E0BE0DD5DEBD081B26E8E0C3521D0124C9A12AF241F623C73B83422EDAA4A2C372FFC730146D211CF1FADCE9C56040D8003D887605EC7E8AD29BC01925951CA00D217F0719AF0D4912E295942B6C12D5271902D901757011F5F3D0002D9D25583C492C5E5CAD1B56865B8927C4927953A492625EBEBB1E3784DF2B1EDA1601A3405E5CCAC9EBFCF66D7EA1205C5A77A9A350154BAAB41371C2FE157184BC9222443D65CC5B703A63422E26671D8731FA0420AFC29C1D2642219A0952D1DD338BEC7C532A0B9D7454901294972667D5E8BA1682979F9283D3CC9 +ss = DA75F7C38E010985947EF930BA6B83E7 + +count = 84 +seed = D0611F9AE5BE4DA5D7EADC9109944348E716CB3DAEE545721EEA8C892E7831CF2E54603146454CBFD92387739E9A78D8 +pk = 7D3FC0511382996C71EB3B77BFE0A16AB73DF026C180B5BA297F1722CFCAB93599F53EEE2E0E642DFDD88AF187AC70B4FFA0714363A20166B7D314A29F89AB12F8EAE2567D383B2F5C244110450D2714A01B6DD61878D153A22A52EC246DE9144B956AE2686F0058F18322B69D00356BAA882DBFA529CB39E45535241AE0EEC6F239F8F4DB2971B1E9B741D894107124D0745ACC064DC7ABB21B6E208F6DEC6BDB5603E90070DEF2D226326F8917EBB48119BF8D7DA4EACF2157002C8A84B8F8A9BDF53D3263E62F0749BAE32A9B89305BCAED3672B0F6BEBD2574015F8B1BCF14A692411EC23CF2A26A059610E10DCDFF9BAB924EE7A10858A69014A65B550CB8823930A38BA84F1BB252C6686B5B4E8C6B0100B81395E44AE10C1FBBF3975F949A7027CDA1076336273A121C537747428BE68F229CB6A7396AB149F5EB21E9C1EFBFBBB2190E9C9900 +sk = 9A86490F0615F3EDF789CB0654066E9E11A2F62A82C999B0ACC95D1C3BA10B734827586C051001754C8C4B017D3FC0511382996C71EB3B77BFE0A16AB73DF026C180B5BA297F1722CFCAB93599F53EEE2E0E642DFDD88AF187AC70B4FFA0714363A20166B7D314A29F89AB12F8EAE2567D383B2F5C244110450D2714A01B6DD61878D153A22A52EC246DE9144B956AE2686F0058F18322B69D00356BAA882DBFA529CB39E45535241AE0EEC6F239F8F4DB2971B1E9B741D894107124D0745ACC064DC7ABB21B6E208F6DEC6BDB5603E90070DEF2D226326F8917EBB48119BF8D7DA4EACF2157002C8A84B8F8A9BDF53D3263E62F0749BAE32A9B89305BCAED3672B0F6BEBD2574015F8B1BCF14A692411EC23CF2A26A059610E10DCDFF9BAB924EE7A10858A69014A65B550CB8823930A38BA84F1BB252C6686B5B4E8C6B0100B81395E44AE10C1FBBF3975F949A7027CDA1076336273A121C537747428BE68F229CB6A7396AB149F5EB21E9C1EFBFBBB2190E9C9900 +ct = FE0559C7DAEC3451BDCEE23E2D82A70CE36625DC8BECC7F58FAF6E38154DAEC257407A75BC6B249CE93EF1211E10E5C2D883ADE723050101E0AF2702B6212A500B40DB8D2166ACE5F35E17509BCE9F93FBD8C0899F7FB2DB97C790E036BB79AB83FA2E33FF2520E75F5B5D109001CC524C58AC794307A1556879CDA453D0D51E39050C86D37962D9BFAF9A8AC7174AA3ECFA0CA0E4CAAC0C0BA6F208800118EAD944546001583B37F18C4C71F54D8E3031AD66688CC4E3BB6115A6DE364AFD2F0204FC77EA8336F55CA22F12A46C198D01C79134029A31047D4B5501B7DA0ACC711530CBB5261221904A6C34F9AAC3926A854609510D4B23A3725A9E45CD444D02B4E0CE3F392EBD7C9DE13774DC349F28AA00BB59233AE46D845F9239D64003E85678FF270EBDEF2834A39CF64166825B803E53C86E5D275999E4E232673D97E3CE93770C60AA5F920105CC6F1C852EAE8223523C1E18E5B6E0 +ss = 389E75A62D289C99CD55DEE471EFD8FE + +count = 85 +seed = FBC38D7614D7718E931EDB850D2C6F0C5EEA9EE889B3E25BD69AC255D5B91E885D93E808E66BF9C88C655DC594DA5792 +pk = 2201048D6ED00F2CF905E3DEC468164C3D86578E06BAB3ED59FC8D3620876CC876677B73B97F2FBB887D9BDA577AE06597876C1431C0002C2EF1A6497C437417F2908BE9F147DE8DE09993F5C024472A4D7593612471F12A248F47A862568DA438EE76D1ADC9E259477CA25397014B9937B9B704E3DA976578E0DB447D280195B307833603681232CDE558466CBD3BF02E2747FD4139CADE697F256A67B1522CCC299A02018A58A2C462A9829745DB219B94FF2C4BF972C523CDCEB2AE7B893A226F248951A369D1E3F4CE68E3AC8E4FD9924AF689A4B83BD6056700339CA542C3B735666ADF91CC52B87816E88F9385CA566220EF24A97695D28DC474DD64ACD3413D085CE9E135B2C51F158B115DD6D0CF0175A4204359581F98FD18C39126B61177BE71F16CB0F37E95403BC2E98B718C9449025B51E4A637B936F5A0D915F6BEDB8AC856185C1E00 +sk = 6DFD9B575872560C7BDC2732C4A28DACC1F19CD6E52710F40C63065365C210DF5DC00930FD2FE896B183D7002201048D6ED00F2CF905E3DEC468164C3D86578E06BAB3ED59FC8D3620876CC876677B73B97F2FBB887D9BDA577AE06597876C1431C0002C2EF1A6497C437417F2908BE9F147DE8DE09993F5C024472A4D7593612471F12A248F47A862568DA438EE76D1ADC9E259477CA25397014B9937B9B704E3DA976578E0DB447D280195B307833603681232CDE558466CBD3BF02E2747FD4139CADE697F256A67B1522CCC299A02018A58A2C462A9829745DB219B94FF2C4BF972C523CDCEB2AE7B893A226F248951A369D1E3F4CE68E3AC8E4FD9924AF689A4B83BD6056700339CA542C3B735666ADF91CC52B87816E88F9385CA566220EF24A97695D28DC474DD64ACD3413D085CE9E135B2C51F158B115DD6D0CF0175A4204359581F98FD18C39126B61177BE71F16CB0F37E95403BC2E98B718C9449025B51E4A637B936F5A0D915F6BEDB8AC856185C1E00 +ct = E304BD1D8E23512AE8C2DE64DDF9BE3D8340FC28C8814F78BE3D0F5CEE0C0E9D901B0536793EFEA9A4DBE099C9F0DC62C5C350FBC410011F59035D58134E1E9BA87EB44326DBA6CF34086932B119865CD3969960D64D99FA630D9CF9B84DD26D2F5A611E9878A4694755E4BE740174F824E123B9C8805A7D9ED689495E4E0D5E10797AC2BA4A52C7AB807A4E7505990F2ED051DD883D5B5A80DD2E985B02F2DEF687EA3B0168EE44D02635B949DDA2747B4F62CC172D98B0B11E90BAD710A80990AC4797D9631178F2268B888E64EB0D2B89ED62BC1C4E0DD0F7E900E742852CCBE351314EB3F7CA2ED494B52F342CDC4BDC4980A90A9E18993523C5CD5108D1E8B7610002BD9D075BB368F6697DE3100D90016FE43A4C6F6C096F0639F7564BDD58E9ECC53620A52AE1BCA052617DEFB518C08C45CC2B29B5E77A3D2D7613DE0476DB5A56480B4EC50066836841752DDA471E6A05BE340ED113 +ss = 57651B54AEAEEEA98B87A7D60BE38C90 + +count = 86 +seed = 1722219CB5DB47374EB0AF0232C856A57F026F1CB09E5A5799F4C333DD422FF6A0A67C4DA502FAAE727FB2D45DAFCF35 +pk = 9900D987D9DE09CDF27B12E7743BFDC905E61AFF645EAF02C67D3778935C42F5EF223B6057EF4224158BCB1C989105D70145D594425600C996218C12C222ABDA46A3F9BB51D172A3558F6EBFB4B92E5F63BFA44D12B1FC6B065850EDFA5997E43F7B7B4A92333D704B19A48527029369A58624E88CD0C12BF76ADC19324696FD8C6E632A37A8F0ECDAACB7DE805C80C5FB7368A3CD40F2F86D42BE61CD660609DF5BFB37017E47F082C907E4CF21650D351711B5D3C8156D077D1CADE204D0118377BF582E3116295482744C3D325AA48356DAB735AB91E98D2569015BB69791A80437956724D843E39F5C4ACB573581941CBE2D1F813D181A75DD33949189F2EE1BDE52BD9013D135DC6965D211924E1AB601979A4B1E9BB82D52F0E3EB6EE349F5088E6D797D7F53211C6531FAF94E68CE1CC8FCA2ED9D2F3C3AF387FCE8A7D4EE6CB2424568E1AD01 +sk = 6FCA9F4E384D8418075CC064C70730801B9B38C17733BA74730C46BF39C6D2440E49B70531A315A6B80133009900D987D9DE09CDF27B12E7743BFDC905E61AFF645EAF02C67D3778935C42F5EF223B6057EF4224158BCB1C989105D70145D594425600C996218C12C222ABDA46A3F9BB51D172A3558F6EBFB4B92E5F63BFA44D12B1FC6B065850EDFA5997E43F7B7B4A92333D704B19A48527029369A58624E88CD0C12BF76ADC19324696FD8C6E632A37A8F0ECDAACB7DE805C80C5FB7368A3CD40F2F86D42BE61CD660609DF5BFB37017E47F082C907E4CF21650D351711B5D3C8156D077D1CADE204D0118377BF582E3116295482744C3D325AA48356DAB735AB91E98D2569015BB69791A80437956724D843E39F5C4ACB573581941CBE2D1F813D181A75DD33949189F2EE1BDE52BD9013D135DC6965D211924E1AB601979A4B1E9BB82D52F0E3EB6EE349F5088E6D797D7F53211C6531FAF94E68CE1CC8FCA2ED9D2F3C3AF387FCE8A7D4EE6CB2424568E1AD01 +ct = 8E4C55A45318D42EC17906C0AB3BBAD6A610931BD794D60414C93B7DE740D08D92B279F30B599CBB72AD29FEF2972B041E4C26505C7A00A44A0C74823588A80E7027BA0474EE3DE013D532B893BA4503C1F9A4B67D8113613741D4302C9F43462C19DCED342A998F8340C91A0F0270BA4D21A17314AA398C863382FDBAC1543A088B81FF17074729C26AC9E325FBBDEE8FD3C0E07D6FA64F321CD32575B0AB9A701005890181600CB562982E4F86D7443DC56B2B965B17C526859066210893C4D7AA20699AB47E6F07C287E3082CD843B6C5F1313E1BF310B1385F019A8936D54EF89E8D11A93C9968B14A0CADDDC54AA8690EBC3CE58B58B900F527AF3DC14412FB391AC5758434967DD39836ADFD6E439800D88A8566B1A765E9378CA02CF1CBA8E44F2751B511957A439C3377227C1577ED73B32E826A0EE6731977E14312A29669B7E057F909F600C7C4C8AC3395B0EBFD758BFAACCB1920 +ss = F6082FA9C2DF2BBAB518B4DE9F489231 + +count = 87 +seed = AC139B78FD16CA0F26D6D7F9E15345C888D857B1910CF38D883339B37EAD2DCAC30F7CF10176F23FF34B4488EB79437C +pk = BDD34E9B75E382D60D8EE5F67B58BC98D201BF3CFA54BA20095E7E16EB3C3D3F80E4D17FAB494E8D2F3B2CC6D6887FFFF567E948ED2602941ED7584BB18FD1E5D370A14ED6C612D689C8516FE5527B06DDF4D44A7BAB2852D41F19BA296FE18F6743DCD3035C2FFB12360015040049194B9C6607B6CF00C71EBD57A6E04B41FFBF7F731CA7E8721BB2A439E9F24BCCE2E70845636EE7B50E2EBE82B17A3B670AC45ED378001F222EC68B015FB84848C139BB2313A97717F1F456E7C0A1A65F2CBDAD1CABD7510700D75BEF0E53B0044F349FBACC3B021E60FA2E3200311ED3CB16DBF2AE3CF60F22BE5411E3C2FBA508B2D6EFC6755D74F1C2AB193D468BB10949C0EE65D3C78BF8B6D62353043B7D3CC20602704365AAA7C56DF5B93EF267484077F1FA63FCA68A61637A23B915A8A11530366A9BA7938D88FE158238DBB5DF43878A96D54F6040B000 +sk = E58F71BF175C0550A67E00E0F7B3B7FC8D3FB72B55010DDAC525AF967662C8CDC6BD65F230E21FEBA3FB3F01BDD34E9B75E382D60D8EE5F67B58BC98D201BF3CFA54BA20095E7E16EB3C3D3F80E4D17FAB494E8D2F3B2CC6D6887FFFF567E948ED2602941ED7584BB18FD1E5D370A14ED6C612D689C8516FE5527B06DDF4D44A7BAB2852D41F19BA296FE18F6743DCD3035C2FFB12360015040049194B9C6607B6CF00C71EBD57A6E04B41FFBF7F731CA7E8721BB2A439E9F24BCCE2E70845636EE7B50E2EBE82B17A3B670AC45ED378001F222EC68B015FB84848C139BB2313A97717F1F456E7C0A1A65F2CBDAD1CABD7510700D75BEF0E53B0044F349FBACC3B021E60FA2E3200311ED3CB16DBF2AE3CF60F22BE5411E3C2FBA508B2D6EFC6755D74F1C2AB193D468BB10949C0EE65D3C78BF8B6D62353043B7D3CC20602704365AAA7C56DF5B93EF267484077F1FA63FCA68A61637A23B915A8A11530366A9BA7938D88FE158238DBB5DF43878A96D54F6040B000 +ct = 5BE2B297C41D5E3DE52E1F48667EC76AD3BBBE167B79252DE2DC3D06CE6D76F0382F4400EE57EA20DFFEC4DE019AC28A34BD8CC68B7E01276E20DAC70D5060660192DFC3B9AFA1C50730D5D865BC7F0D9D6CAFD5817853BC9F76E083A6FAC476F90EE7506F5B68059C263E0DCC01CEA739DF7D52D8032E2CD934F5119B03E70F7ED3CF4ACAA84A6524254934D4CB2C875F1FD7945474282388903FC3C7D0A7EE4CD2AD3E00138B27ED81369AF50C8B1FA5BA7C693CA98400ECFEA59F1D541A92DBB6B92752FB164C775AB472F08B949E73C136427D4594C14FF1FC00406ACA2F65F37872D498D7E58C73EEE80C96CBDD21FCF1C3EB172862A54773EF59542BDF8DAFCFA1241EC187B7A9AC57E35A5911123D00CD387140A2EF8ED2AC15D2FA06EBACF4E279E617947A6822B62A72C35ECC938A3A9FC3FADD637ACB556D758019B08D82A1469106DB1C029A809215BCCE9EF8557E7593EC2DE97A +ss = 35C62EBA540CB14180433A41CADE8988 + +count = 88 +seed = CC7152849C98D5FED2813275D32069E44824ECB14EAEF425CE017448CD9A401C91C06D0F7EED6D22B7BBE8BA6C429EC3 +pk = AF9DF3DB2FC633DCD52B4448291577FC5DEF87F572DAB9200658EA0071EEAC78B3F8B2106F5BCBA7DA7683E6CBEE6ADC236361623AE40116C77436B7EE5BE3077E09CE4CF9219C6794B1C781B225EBB16FAA9146D94ACDF01BDFF1209D8A31F15C63300D057321D995ACD71F380067197909D44A9F0B58D7C59045465AAC0C2171C798A0E8587E70F5C33E6F694528199D46EB633FF3C8BC5196C6E8CA6271077E4C26C900601E49AE716EF3CEC7858BA6227EA9B576A5201CF1712FE8578BF2676DFC2C1013986E48DBECA4444EE24F5CC9442931C7707610DA6D0081A2BA37384162E842A09095AF7E3228E2123C4F9FB2AAFB5BFE5F849C8BF20D46F977EB18143A09B697969A6D11CFD6D21F0EAE4663011320CB23679907015C27757D451AB2B775EA17AF603D04E4A2EE3C237A94DE32569225C4E00331C6B98F9D4BD0C0FC916E935655A9D800 +sk = E3FC575ED51513E62ABA655D24CD9C8FEC49560745A08FE9D8341C3F25F459B64EA92BD0C6C7FA16A35B3D01AF9DF3DB2FC633DCD52B4448291577FC5DEF87F572DAB9200658EA0071EEAC78B3F8B2106F5BCBA7DA7683E6CBEE6ADC236361623AE40116C77436B7EE5BE3077E09CE4CF9219C6794B1C781B225EBB16FAA9146D94ACDF01BDFF1209D8A31F15C63300D057321D995ACD71F380067197909D44A9F0B58D7C59045465AAC0C2171C798A0E8587E70F5C33E6F694528199D46EB633FF3C8BC5196C6E8CA6271077E4C26C900601E49AE716EF3CEC7858BA6227EA9B576A5201CF1712FE8578BF2676DFC2C1013986E48DBECA4444EE24F5CC9442931C7707610DA6D0081A2BA37384162E842A09095AF7E3228E2123C4F9FB2AAFB5BFE5F849C8BF20D46F977EB18143A09B697969A6D11CFD6D21F0EAE4663011320CB23679907015C27757D451AB2B775EA17AF603D04E4A2EE3C237A94DE32569225C4E00331C6B98F9D4BD0C0FC916E935655A9D800 +ct = AA8140EA0B7FBFC506126531274EC76B02E73F1F46E2EB3BEC4C98CEF595F901380ED823D3F474242D5FA6DAB20227940F05CF254303012C19D48EA45EF6DD4E4E60B9B618446342FAA480519C5978B31A4AB51FD833BDDFAB1EDC809C9BBE47E730577A71E5B8F66FBC8CD4D4015DA8AC2A2EFE963D2C94BAEB38F7C0ADC2D31EC9A9C5337A02E1B9FA4145F55A2A8E6874584006C79DC3752B4DF8782FF0A4377BF24800FAF73684FECB522B1EFFDBF6C8A7205076C3E290692D3C1277137A0F83869AB3ABA3D1F99B94F7CB5F30FB049A27BA03C570755F1CF100A516C84A748AE234A6892CEDF0997B859D5A87E14F1D2C6B9B5A91E8B80882187B97407E498A6142E12F49E200C84FE4FD8383DA05E401C8B542EBC56A9BFF71494C9643E321851A9EB15535ABCC3974D8FF46410490B0B5AD9CE77623F945A2EE95BF3E7EA63B9167480FE49E007BA7776F5878BB63181A7DB3F79F4331 +ss = 8FBB1675631012AA69F22561CCAFE1FB + +count = 89 +seed = 96D9A06F88FF2C2036FA8E914B89C765E4A510B468DEE40F914F78858C811857EFE9FD0E17C0048E7389E8D996B7E2B0 +pk = 25866D1F4A0D7F7252C128D035CA93460542C32E545077D57BEA62FFE92C37B83C040ED2D7E2341ED7B406D1D9A0BCD82BCE3C9BCE1200E625EEAB1A74EC3AF9E0B18949627E0890A949DFC367DB9C0915A3541422B9E0CC632B45ADBC0F18E749B0875869116CD6145DE3BC540067F8E8BAB51AF4005306FEFF6478F567CE0B0476836606E7B7FDBCD888A5C863ED338C0B2DB7FD99220D84EFEF722D78A262081404DF01EF4AD81A528EF02650A4B8F1F4EAAB96B467289DF861781F4EF505A09EB95FD54023597C23E0DE8AE2942778F967C1CDC688E4E1161001EDBBF26CA03005DAECBE4C672662778D42464190C6AA95B0906B3995CB99F02D16413F056635BADEC34DF3B43EBE29866FF6FBB64F2F01E87CE3EB63B52765172361823F6981E02CA2BF33AD5FFB2B062F58B44FCB8F40B309E80278A804D9F6A572B5FA936BC391FA95686DF501 +sk = 470B4943F0FE7FD0D8EC5185ABA0D1DB7CC710FAF7C1C1F4A4A8419DEB87C915EF692895903BAE280771460125866D1F4A0D7F7252C128D035CA93460542C32E545077D57BEA62FFE92C37B83C040ED2D7E2341ED7B406D1D9A0BCD82BCE3C9BCE1200E625EEAB1A74EC3AF9E0B18949627E0890A949DFC367DB9C0915A3541422B9E0CC632B45ADBC0F18E749B0875869116CD6145DE3BC540067F8E8BAB51AF4005306FEFF6478F567CE0B0476836606E7B7FDBCD888A5C863ED338C0B2DB7FD99220D84EFEF722D78A262081404DF01EF4AD81A528EF02650A4B8F1F4EAAB96B467289DF861781F4EF505A09EB95FD54023597C23E0DE8AE2942778F967C1CDC688E4E1161001EDBBF26CA03005DAECBE4C672662778D42464190C6AA95B0906B3995CB99F02D16413F056635BADEC34DF3B43EBE29866FF6FBB64F2F01E87CE3EB63B52765172361823F6981E02CA2BF33AD5FFB2B062F58B44FCB8F40B309E80278A804D9F6A572B5FA936BC391FA95686DF501 +ct = CCF491F399710CD48DB7AD77A77369B6304B73FA1CD567010FE8B47E58CD801B4F40B9857590DDD69BAB17F316FBD8A05392681089BF01EFA3FB36E9532A0FD0B05DDA37544AF71DA6677DCECF1BF62D611F39CD7E842BAF9078D706F85BCAA06F2885F6652E0F907E60D1C68D0017570AF6730C69D84A9BE48EE1559E0C5ABF4143CE492C14D2573006C73AB0C9BC7A5699D306E40929811FF695302B090EF0CC6152E0019317FBECC106907E3D4CB85E0A93D07DCCCBE7AC61B365652EA3D955E81A4A986B46BA85CED2F8E2509EE1D9F4A51CBEABC1A0F76B080148BC0DD9800C403A618F53CFB485C946D1C8D2B6E6E9B6D6D6076F1A2F22F5C574DDE4A9C764282C47FC5DC1CC5D3799AE906A2132420108B82ED09D9915A1121EA97FBED7DEAE58A6658BEF2098A0A0FD588EF8D34250198052693CB95270160743791370BFECA4B54A55840500B4FD3BE468B107651404EBEC9F0E620B +ss = B3076F1E54E9218D8A56359AD11267AA + +count = 90 +seed = D26CE360D399BF7B89DC364AA7AC06BB513EAB8F527383E93E30727EDC3F22C262AA0EC70257B39EDFF0630DCDC1B79A +pk = 7DCBA0D39939F14443FBFF5A5A7655117CF4ABDDDAA931E1F9F5F2F4DDD9F23D9BD14405C885A5FF48C19BCA55E85CB6C994329FDF410142E78EF67F6502759B0BC2ED49EA8E69B0F0662080803F6D3A08AC2FADE6515F238482328C0E97C96CBC6134BA569870A27754F32D970186491403DA9C984DA754BB8CD3F2A2C117EF7BA1FB1F9D24AC04F989E6DD1EE421EEA63BA820E435D0EAFBB535C2AEDE244CF1EB43C9016BE24B68B1393512CC8E6DC4A0B9B2C8B8D9BBC0354D592101CA78F7058B32DDBE732C7752D489D4774049A25FD8F58FAC2A95B7BDB60131B6C1C121EB81C4C86A79813538F7B4E4FA3FB72A82A33C8DFC5073AA7B9D5BC01E10AC03FBF84045C718CF108CC4A5584E205E2DB1014F901110951736A4CC27F72E0CE59D4BB32A8DDD9E1699D59ED3982689C0576E009784E07526F45EC75F6F0C3C6E5D358F0A848485E500 +sk = 6DF4385DB978D27B27D2AA5E452E41529B8E8792F075F00ABD73FC790D3297EF894C5475CA4323B06E63EE017DCBA0D39939F14443FBFF5A5A7655117CF4ABDDDAA931E1F9F5F2F4DDD9F23D9BD14405C885A5FF48C19BCA55E85CB6C994329FDF410142E78EF67F6502759B0BC2ED49EA8E69B0F0662080803F6D3A08AC2FADE6515F238482328C0E97C96CBC6134BA569870A27754F32D970186491403DA9C984DA754BB8CD3F2A2C117EF7BA1FB1F9D24AC04F989E6DD1EE421EEA63BA820E435D0EAFBB535C2AEDE244CF1EB43C9016BE24B68B1393512CC8E6DC4A0B9B2C8B8D9BBC0354D592101CA78F7058B32DDBE732C7752D489D4774049A25FD8F58FAC2A95B7BDB60131B6C1C121EB81C4C86A79813538F7B4E4FA3FB72A82A33C8DFC5073AA7B9D5BC01E10AC03FBF84045C718CF108CC4A5584E205E2DB1014F901110951736A4CC27F72E0CE59D4BB32A8DDD9E1699D59ED3982689C0576E009784E07526F45EC75F6F0C3C6E5D358F0A848485E500 +ct = 20759960EE23EC88F2C37E4DDEC502DD0CE3F3FFF4D7A71E4E61697CC78519D2600F0ADCFD6414BB080E0E6B4D95062D7F651A1716A8001A3C06D9BFE74DC8F8B3FF7CC22118A684135337CCD45DEB75A886F833862C41EE2DEEC0B7EA60FF56DD73123D8CBF4161AA4A9E68C001D3AA5C25064926AB4E68E646E3C58C02E28B2A6FB0F99129F804FE508231F03A4710080FEB33EA46AEEE07EF7D3681E053E8B5029DC201F49C93B0360C5AA64ABC98B72BBD7429106E80F14C7C47705BF68D7B5B77831A97BD467C22A54AEBDB1AF35EDF43095871D1B3E4D931016E5431D56BD566A4E180A20E4BCFBCB9F634179403916F2A83617CEEE981CA401CE6479B7B238A5175DD21D08BDC6914DDCEFFB08E07005E10E3FD52CEF9AF4E3A3D8E68938191D63EB207BA736D71369843D7BF7F5FD5A16053688C475939858B80DED3C01B049FB09DBDE5DD004668C5F892C9845B7034DE3DBFAFFC76 +ss = FA89E11860344D23EF3708B4E18E6228 + +count = 91 +seed = C5856298C3CB6AC9787A0F30938537AB2635B96F6D19CC9522063360E7A5C88E644929D2879180E3E5BCAD2422B7CFC3 +pk = D838126D3EA3E3B661E4533ED9718149448B1E506E14B8B04DA7F945DDCF4B5363733086D5FA5F4E250EE1E8447827103EDF71E80F2F009600AC670B23DF0C598BFC21C5F5D9A25A03053380D148DADE2CA60626E0339489A91CD6F81C38039BB09E93D94C79584C79AF201954011623DDDEB03231F99013AF1595CAE2438F4013273673527DB83F7F28D3A13887910891EF3AB644059E8DFEC05CB671683265BE53BD3901FBF356BD8794AD73F644F527D24497A25110C24808DF4F2B924E71D99A33440C33DC84B99071EF05317DFD2990B193A7C54143D59FF301EFFB7B94A46DA50C7915FBCFC823E36B39144CA8F21BCAD4070ECEB81F13F7588986C90555390F096EC1C3DC2BBE0F218BE4F3A06E0A00F65A67CD56D9A18CFC51867D0C38293FB226F8855FF20B95C5C9A9D23126CE42A08382F03BDB5E9CF5E01C164EAE3DBABB2690B54B6E01 +sk = DBACBA825728444921B227CDBA54446B57D37B8DBFF080C604AD1E083CB0F9E3A2D62131ACAE982E474B6201D838126D3EA3E3B661E4533ED9718149448B1E506E14B8B04DA7F945DDCF4B5363733086D5FA5F4E250EE1E8447827103EDF71E80F2F009600AC670B23DF0C598BFC21C5F5D9A25A03053380D148DADE2CA60626E0339489A91CD6F81C38039BB09E93D94C79584C79AF201954011623DDDEB03231F99013AF1595CAE2438F4013273673527DB83F7F28D3A13887910891EF3AB644059E8DFEC05CB671683265BE53BD3901FBF356BD8794AD73F644F527D24497A25110C24808DF4F2B924E71D99A33440C33DC84B99071EF05317DFD2990B193A7C54143D59FF301EFFB7B94A46DA50C7915FBCFC823E36B39144CA8F21BCAD4070ECEB81F13F7588986C90555390F096EC1C3DC2BBE0F218BE4F3A06E0A00F65A67CD56D9A18CFC51867D0C38293FB226F8855FF20B95C5C9A9D23126CE42A08382F03BDB5E9CF5E01C164EAE3DBABB2690B54B6E01 +ct = 437A2D3D5E514A9917FB25F0A243B9325BE06E753C9C8B878D2A33EC9F555FF8DF5287A8E5457AFAAAD7B8FE78F535434701D4BB6CCD01849FE169F0FDB7741FFE0C66C4DE656458CD99A78B2FDA1E36B06FE89C717EF5D1BCD3585FA8C36D2D23166E1C38CDA1A546C2EE9D25005A592C1CB0CCFBE6EC30509821AA07665E2879A069D709AA3BF53BB53651AB346DA3D582708E048A991D7F8461270931288DEDDEF742019D56A0CC3B090830DD14CCB776873EC6AB5D159E279A73CB169C9C134181204D76932EC93F9DC838E052511DF847AD00BF178E39F97F01249C1743D004376699737065358849455CACA0FE5F5B862DBD9CF4B706790332A102C15474E86E28EE18A285F6CB711B9B27FF985A36005478DC8587D9DDDC1466DD5BFF9E10A96FDADF4DFEADD82BD3F34EBA11CBD58380E230488BD2360FA09D53E8CC55BE96387A1A182B8101E7665FE175858B343D2FBA387E687587 +ss = F835B064E9CFE827C979E4DFF55328F6 + +count = 92 +seed = A28EAD0A08E7228AEFF602B16A1E752278B8ED1E91DAC67994F5ADC372E1D82F95CC390CD97AB9212275E0566C833FD8 +pk = 6DA0E28267DB90F6806DDCEA27C6ED27E705BD19D3B55D888CD80CF5FB6FD4CC9F23C153DEB2F60AAEDCE6A260C6F3F1149FFC18A11601987B08AB82E4C6491D4C5585D1CEF2ACA680BC9C6F5DD37FEFF246CBE0857C4CF908DA5652A758EE0EFEA2B5190D68CE636123CCA6A901013217821CE88544701BCC901D4989BD6F42301AFEBA63237A6428E6802664A19BB01EE6CD593184DDB95E93D31D4FCDD34993607FD101DBF5DCD2BF6BFACF5146F0B75914EFC75399508A812729AD193FE6CE75BEF0D94334B0C1E6F2A4FB259752DA8A01AD77789E725C4566018963093F70468600010278B726F20CC9B741CE0316BB3086CBF25D4696E2A06FD0DD2DDD6D13296505E57DE49CF68B0E56BC38B588CA004152D78E6DA99F9A123610D024B3FBFB9F64FB2800F20338BED72CE49AE5DCD1D53E3AEB5F53E94BB25A0C8FD5CF9F9F068A9DB3755B00 +sk = 690EB71FD7052B906EAEC09937A8ED37AE13ACA45F612D2872FE359C4A257A10CB6529A031BB0A93601B30016DA0E28267DB90F6806DDCEA27C6ED27E705BD19D3B55D888CD80CF5FB6FD4CC9F23C153DEB2F60AAEDCE6A260C6F3F1149FFC18A11601987B08AB82E4C6491D4C5585D1CEF2ACA680BC9C6F5DD37FEFF246CBE0857C4CF908DA5652A758EE0EFEA2B5190D68CE636123CCA6A901013217821CE88544701BCC901D4989BD6F42301AFEBA63237A6428E6802664A19BB01EE6CD593184DDB95E93D31D4FCDD34993607FD101DBF5DCD2BF6BFACF5146F0B75914EFC75399508A812729AD193FE6CE75BEF0D94334B0C1E6F2A4FB259752DA8A01AD77789E725C4566018963093F70468600010278B726F20CC9B741CE0316BB3086CBF25D4696E2A06FD0DD2DDD6D13296505E57DE49CF68B0E56BC38B588CA004152D78E6DA99F9A123610D024B3FBFB9F64FB2800F20338BED72CE49AE5DCD1D53E3AEB5F53E94BB25A0C8FD5CF9F9F068A9DB3755B00 +ct = 361D97A81A7DFB50942054F79A2BC7BBFE98E517AA5F1FD7213EA394D48EB268FCD28FA17FCB9F2059C51E7113B266738683FF5576540173540156357E38F991AB9D4055A98C0C013FE4963C8809E7DED72770245841EE207FDC3FF6E64A4CF5B336B1D1DCDBA8FE2EBAB91372003285A261984FA23DD2ECAC81873C1BF5691E2F7A4646993AD5C60EC38BE067F95810A41277DF9897C996C7B7F1CA568B2D5B7DC2CAE500173A413830D124BE7AF8E88189A03B52F9AD66BB87309EF8F4ECAFD9ABD3983C27379965E42D0DE825CB9C1FAC3E641B5AE33EEEDB0B00D14EE300BE12EB1D40DC102D09A4C3986D7F2F64E6E68C47ED5FE2679244440DB55B08C1F26B068A0B2C021114B369439B1113760B26029E70157169FA9A07FE02595B1EEA8C94C40CB696FF405034800DDA5BB0135179DE6EE04D37C563E46ED8AC6F84E1A40AA00D13D87E6F00FA81C28A68E85543A3A9D4194448B763 +ss = 2A25258531402CB564E80DFDEB153127 + +count = 93 +seed = 92877D706DAF88EF3412EB143DB8CD91BC047A9A43B7ACDAA42523560DEE4C172697BE4332042FCAB91135839BF74AB2 +pk = B0752FE50387034F5C50E82374D7A3BA05860AB4DAEBF4233AF0F89E5EA2A7CC95A5B3A3A530161039E2130D6C6F3DDFF81DA1F1BE050022A8B6607C2C02401D78BDB8850735E1DA52EBB06831DEE52E8B33DF0EB4E3991B69B65644ADCB2173EF9F2172A86DF492AF319E605A00BC6EF8E45B86A267E5B5AD490E07B3273163C59EC237FE5CEAEC739E6D1FAD00C8FE524D846B692CAEBD04D10EC58DBDDC57E092E98400C879555CFAF770888240BF5F55046815520BDF0C8CB196396794083A7EDE185B27EA64A6F3B4105885A00530B7A8B8F0FECFF86DFE4E00D363AE905EBB45F23795DD153C02948583C271F8B60FC5EB55BCA8FD561D4E45B9A42C39DD79568A950EB5DC1043BE519610E34458300207A2FD97AD5F8C0C2059D00462B0A9C26579380F39184031DC53E464CAD7ACD106938304AA82B0DDDC50C1AE065B2AD6E1A725B86EA900 +sk = 32E0EA9089FA928482C0770DA545AF1B723ACC261D1CB8D2A37A97233611FB50B68E83E8FF42DF78A4C18A01B0752FE50387034F5C50E82374D7A3BA05860AB4DAEBF4233AF0F89E5EA2A7CC95A5B3A3A530161039E2130D6C6F3DDFF81DA1F1BE050022A8B6607C2C02401D78BDB8850735E1DA52EBB06831DEE52E8B33DF0EB4E3991B69B65644ADCB2173EF9F2172A86DF492AF319E605A00BC6EF8E45B86A267E5B5AD490E07B3273163C59EC237FE5CEAEC739E6D1FAD00C8FE524D846B692CAEBD04D10EC58DBDDC57E092E98400C879555CFAF770888240BF5F55046815520BDF0C8CB196396794083A7EDE185B27EA64A6F3B4105885A00530B7A8B8F0FECFF86DFE4E00D363AE905EBB45F23795DD153C02948583C271F8B60FC5EB55BCA8FD561D4E45B9A42C39DD79568A950EB5DC1043BE519610E34458300207A2FD97AD5F8C0C2059D00462B0A9C26579380F39184031DC53E464CAD7ACD106938304AA82B0DDDC50C1AE065B2AD6E1A725B86EA900 +ct = 8856885697463E14E39727634BB9AEA15D10267A483757040932975984705C4B9CFC0D456996F75490AEFCB3A6B7F0C0E748DF38E3D100FB00397DA23E2AE89F6D06D3C1314866DDE41B4FB5190D7EF593359DB218596B65FCC87644DB4883FC0137ECFA2563B14D8F959C9E15000769465C716FBF997E202FCA0E619BBA0AAA5C814D48238D29CD6A881C27FAD848CE1CEACE6EBB82E7E4F344D89EC239156F3971DF520092E67223709D6B30482C1BE6E421363B3E2E5E8D92C1C187D98574E602FE43E81AA46C993BE2F1270783B15C7CCD5078A398030AE10002A565AA26FA49AF27DB486D91E1B37C8734D0E14C3F1D00A75B46EA5029BAAB713B34A50722734B9790D6586F2CFF9135BEF934C032890147CCDB71AE0E27F5067620B76B1AAD188909DBEA73BDE5FEAAF2777C6735B4F1303584269720A61FE6A75E492392C2976A57E3D5F1BD01175B6C09AC1F9A6A856C78ED17974CFD +ss = 878871AEECAEAE84525E0D7E98CF15DD + +count = 94 +seed = BB4C0082CA4044B1FF60B036C9B0E0495D58667156786C530BC69D949A13BFAFF53798E456423D7A0E162A60039367D7 +pk = EEF752F86CCEA1E6C9C0848E1369C7FA877089AC893E5813A3CEE8CBD0DC0DA37A7C83E7C4A820E5FE846B3B8FC0AA2E1C8FC43BEF8801EC824239706167BC4637378F44721D54FDE0587BE315952982BF9F531C32530A79C8B5CDFD9238AE0B3C84191312C4A0FE21229752AE006CE35A4D62082A86C1765B95D55EF628E755DEBD1FF5A81D5F5353F2ECBCE86969E75540BF372557D4BC90230FC8396A5F4B22E512AC01C6B1A4CC4BDD339903921B1BE7895979C934697375339E04F1CB75A6561FB60601B5690701FD34752A46A947D242462A9C0F3AB9866101CD9520A373D912E32E4C8B96792D8D153221316BD1150ADFE8293B0CAEB06BA4CA65BCF3AD1AE253984DAC8382BDCD080C4E67264F0F02F80BC0F35B56632792A04C0E06C8C61A63C1E494A45EE62C46A8515DBC724887CA35E5B90D7F5BCBC5E708D72C5A0E58FFE0ECE7F31900 +sk = 6FB2EC719F2A0DEA152BF3F64B9D148F4F78ACBC55E7D2DE144993127EBF1F1772776A06EF9492DC17EF3A00EEF752F86CCEA1E6C9C0848E1369C7FA877089AC893E5813A3CEE8CBD0DC0DA37A7C83E7C4A820E5FE846B3B8FC0AA2E1C8FC43BEF8801EC824239706167BC4637378F44721D54FDE0587BE315952982BF9F531C32530A79C8B5CDFD9238AE0B3C84191312C4A0FE21229752AE006CE35A4D62082A86C1765B95D55EF628E755DEBD1FF5A81D5F5353F2ECBCE86969E75540BF372557D4BC90230FC8396A5F4B22E512AC01C6B1A4CC4BDD339903921B1BE7895979C934697375339E04F1CB75A6561FB60601B5690701FD34752A46A947D242462A9C0F3AB9866101CD9520A373D912E32E4C8B96792D8D153221316BD1150ADFE8293B0CAEB06BA4CA65BCF3AD1AE253984DAC8382BDCD080C4E67264F0F02F80BC0F35B56632792A04C0E06C8C61A63C1E494A45EE62C46A8515DBC724887CA35E5B90D7F5BCBC5E708D72C5A0E58FFE0ECE7F31900 +ct = 6DB5EBD78172494CE2632DC81F94CF776DDD3474FF190EC6AA62D0545795FAA588446F814322DCB94D6F67985D003F33C32188E55876015C851687E3B39465BE6E02509626AB4F5E87EE6A6E0BC3EBB20A98FD1C467A7BFFD343650EE27DF889B541E3A324431017A0E27D74A001FF79284A3A8760768AB96ED6F5725EE6D9B05C34C5D85BF8071E78A9B5BBFCEC1425560F9220A4C5D9221D63B6BE969B2310F2AB023500D969B696ED1BAB48782E3F2FA1746AE18D5F5DB3FD64FC551203900246A1E9F513F49C15DFFCFD41C1363085090AA9403A7EF820F1F401BD745E61C07829BEE835592CE1FE04C53FEF4206F8CB176D0D268F47E7B73F9798438F943DD7ECA2BF69FFC88AD764E77AA3EF29C32B00153A06AB5113183985585C9F8354D6E46A2874C50266202EDE0D13BD2A730E37D6814C5BBEA973A530083AAE5B0E4184DA86E7984396016A8FA6DFB656BAFC94D71078977EF9A0 +ss = 6D17E0011D13654679310C7137BEFF80 + +count = 95 +seed = 121D90E70AF6204445D0DEB28AC0C108262719E9FD3476ACA74BBFDE89FAF04D8D5F89A624E8A75DB80431F0D10AD28F +pk = DEA4B4F99F6DA453BEB0685510197F37003DF8F54BD47D94BC6171CA1C14C7BB4E0138FE8FEBBD6C404B7C8B7BA44E66C7719F1FD99301B6EEC117E382EEBE62BC4E54DBB9EFC66FD08F0A7F3AF75E36D8510E718CFE913694946508245D73B1728444980219ED694782E4561302D21D0C5A6E2A3B19D5E2E1327283F7D6910C105D0537E86006B2934D9BB4B61EE6EA2673F213748BB59DC918DAFF9A44B13D4B16C08800B90B6FC87CE105DFCDF415BA6728D86E08417AE3FE1C2F23075F5261EFE0A81CA5CE295EF0A85E46E42E65FD0F7E48A90208E866911702B0B26A1390B562CEB48AA4CC72A34A6BE2B5A852A8502D0304D16A7EC496F572587BC2CBE9FD62EBB9DFD8D6B882D6B8B85EB9FA215E01AE1C5D34847DE14050F4BA90FC7E7F5539076C8B264F98EC31CB3C248DF74F39CDAE95B3F6E208D57BE9D193CD26D7D5D6DC283C5D6501 +sk = 527FB88C8BD9A4D6031DAD15E63878AB3CFC649838B9AD33888C4E00E4172248814F91B15CC2CC8E0BE30B00DEA4B4F99F6DA453BEB0685510197F37003DF8F54BD47D94BC6171CA1C14C7BB4E0138FE8FEBBD6C404B7C8B7BA44E66C7719F1FD99301B6EEC117E382EEBE62BC4E54DBB9EFC66FD08F0A7F3AF75E36D8510E718CFE913694946508245D73B1728444980219ED694782E4561302D21D0C5A6E2A3B19D5E2E1327283F7D6910C105D0537E86006B2934D9BB4B61EE6EA2673F213748BB59DC918DAFF9A44B13D4B16C08800B90B6FC87CE105DFCDF415BA6728D86E08417AE3FE1C2F23075F5261EFE0A81CA5CE295EF0A85E46E42E65FD0F7E48A90208E866911702B0B26A1390B562CEB48AA4CC72A34A6BE2B5A852A8502D0304D16A7EC496F572587BC2CBE9FD62EBB9DFD8D6B882D6B8B85EB9FA215E01AE1C5D34847DE14050F4BA90FC7E7F5539076C8B264F98EC31CB3C248DF74F39CDAE95B3F6E208D57BE9D193CD26D7D5D6DC283C5D6501 +ct = CF2BC01EDBCEDFE897C3434A5D7F84BD2B7CB59B6769CBB339C92B30948ACF86D369FD657EBB63FD88B2F7593F119AD3A443A1E7632800316571ED3571D3E41D15F370EF945ECC7D8536091A5A8A97E2CB40ACE7D42E6F6BEA3E783F7285879D9AC1AB9100169C4C3A319297230066CD25B855743E14A055B396B07442EDC6A0A1B82A454081D2454AE2D962F8DEFFB45DA51F60A1DB5DC56F0DAE294A4278E476A8D2F200CEDA74A7816855B243B02D1E7946E5B79B132C6CA01430B9BCC67935640A3A0042249CF5ADCA0E1847AA77C0CAEB650FD9FAC193C14F004FC05C5178DAFD2E7BFA3895690A9F369B013CB23DDB483C4F1C482334CFF05A85EA7EA4A1A9186AE4DCE68E5A6CE63D859629F77E37019A7C8FCA32FD69AD4697F19C5165B0458E2F60839D59CD83A080EF87C7AE8D62744C134DC87D35D7253997FEA62FD566CFB733DD532501AD45356C7F9E726E941432CC0D28EAFB +ss = 8C41BCA14516014306BE132DC6EFDDDA + +count = 96 +seed = B3AC6503206ACCC2A92CBC210D020A2654726911D11CE676AA04FEAA08AF1D20C654E4105883AE470EC3AB299075D420 +pk = FCA24F4391DD603BC837E1943024C8AC4694356C42C324BAABC61EC0A32ABA45130FAC2CC13991F65F0D78B3106F42007799D14618DF015886196C948804F388A365A5E0240489AD6D93778C9868C3CA68125459C1FB8D170D679722340BE2906D8BA011AD7DC8E452A00CA2F800FBC219F2FFE71A45B05D30291C8608411D0AF98FBA4F441D5A319E9A8208EA689671D962FA0DAFC03F889D807346E393D14ED787ED5C0034FBB2D1F7BC30B5D108D87AC2B3132693EDB656894CD08B51252EAD45F07ADCD4E0365B5AA9600D2DB0C77C1715E375839EE1DCF9BA0052A0166229B30C97661250A4D65117E047A0E6A3626BDECD94ED27FBC3FE661ED669EC5B980FD42A9CD23A95912E2D7AE8C5B60B563101B0B66CCE2AC11575C0F8A20612D106B01A582200EB9FBA2D4C8B6929A519477ED91DB66279BEA619B34F9018B01093CCD7CD48A5261700 +sk = AC6FCFAEEEF795B6EF9E062F02BF4297A326609323DD9C830DC4537008A8393CE51A77519268602BEBC88100FCA24F4391DD603BC837E1943024C8AC4694356C42C324BAABC61EC0A32ABA45130FAC2CC13991F65F0D78B3106F42007799D14618DF015886196C948804F388A365A5E0240489AD6D93778C9868C3CA68125459C1FB8D170D679722340BE2906D8BA011AD7DC8E452A00CA2F800FBC219F2FFE71A45B05D30291C8608411D0AF98FBA4F441D5A319E9A8208EA689671D962FA0DAFC03F889D807346E393D14ED787ED5C0034FBB2D1F7BC30B5D108D87AC2B3132693EDB656894CD08B51252EAD45F07ADCD4E0365B5AA9600D2DB0C77C1715E375839EE1DCF9BA0052A0166229B30C97661250A4D65117E047A0E6A3626BDECD94ED27FBC3FE661ED669EC5B980FD42A9CD23A95912E2D7AE8C5B60B563101B0B66CCE2AC11575C0F8A20612D106B01A582200EB9FBA2D4C8B6929A519477ED91DB66279BEA619B34F9018B01093CCD7CD48A5261700 +ct = 37C15E41D44325B5DD3B601386B51EA5FDDFBF664959D3F64C91DF9575BD6FF00F578C1476970EDAA6DDD03C60E41E2F93D99E61FF2900FD7DE5371D19444973F4A41700B83B117664F0F3D6574EE5C3D99FB51102186AA0C77905EC6B8A8A9D82874BDF1CD209E0ED65170A6F01CEF4D39772FBA2303A8782412615565C1F5EAB75B651F79680BAD0BC91FCF3739F78567718ADD27CA077F21306F3B1BA95F223D1C44C000BC4A61EDBD2E1957F988FEBB118546D65A141B584ECAC9440D87B176EDA65011ACDC5D88B92D26488C1E0029AE84051ABE12590DE25016A0F4ACA9E68528B22A2C53B87333D669AF8DA2C80F8DC14D62AC47A20086F454F965D65C19392C811F7A15C09142624168C1337C44300562D058B1A1F42C05A3393FDE7E843DF97EA6260A69B706AF438C1B03F6506DCEB2ED0842C91172E7B3025C53213929D4831F1095A3400D6A130A811F1B33CCE37D4077D77159A +ss = A6DB9C606E364AECDF4AC552B41757DE + +count = 97 +seed = 59EFF60B1EF6185DB34EE1E3B1DD2F159106CECEAA79BEB74923B4F5623D5BC52DBF5D2594A1F7C6C64D12CF144E9ED4 +pk = 39261E697967B0BB7EE0AD5621B7C62179401C8FCCB5BDA55776AF330E450DAE2E5B7241E9CEC5A2C09514CB96CA35A7BCACEB781E6500D62CF7ACEE028461D8A542F5FA2B7FA25147D62AD481F97C4E2AAE52C6B8AF0D5CEFB771E4E42FD707FEC2B9BE61E403D211DA70AC6801BD0472EDAFAF17A0DD1D772D3B39FCE955FD37648EDE750AE8B707AF6747A1EB53A91EC66C25F30DDB3171C8D83A8114DE7F722460BD017811EF82DF92339BAF90291CB3B37879D4795FAC777793F2DE1FA2724DF4EBE6CB6C0EA6BD6D9548D3AF8701E21292B6791D2A9B0E2901A45B0C8CACE6E2F70172B04128CAE55DCE6B0A2EE31013D6765E7C027A6985DEC8F02ACD09D4BCA7F79516D4F3F4965EB572717CB3BB01FA8871B8D508B9DD59342A43AEAEBEDF788AB4A64585C0C0CB33E1DFB3063566F3B549F4E801AEF11420094EF1143F2D9C84DFBE574301 +sk = BA2FB9318D4DBE7488057C33E95E6F056939B6856262B11B084EF55E11ABB72D2062CEAA72A155F0B158F10039261E697967B0BB7EE0AD5621B7C62179401C8FCCB5BDA55776AF330E450DAE2E5B7241E9CEC5A2C09514CB96CA35A7BCACEB781E6500D62CF7ACEE028461D8A542F5FA2B7FA25147D62AD481F97C4E2AAE52C6B8AF0D5CEFB771E4E42FD707FEC2B9BE61E403D211DA70AC6801BD0472EDAFAF17A0DD1D772D3B39FCE955FD37648EDE750AE8B707AF6747A1EB53A91EC66C25F30DDB3171C8D83A8114DE7F722460BD017811EF82DF92339BAF90291CB3B37879D4795FAC777793F2DE1FA2724DF4EBE6CB6C0EA6BD6D9548D3AF8701E21292B6791D2A9B0E2901A45B0C8CACE6E2F70172B04128CAE55DCE6B0A2EE31013D6765E7C027A6985DEC8F02ACD09D4BCA7F79516D4F3F4965EB572717CB3BB01FA8871B8D508B9DD59342A43AEAEBEDF788AB4A64585C0C0CB33E1DFB3063566F3B549F4E801AEF11420094EF1143F2D9C84DFBE574301 +ct = 0DC86F3AFB7047767E12D21BCE9308FBED0CF6E673632F078313E67B07B58DBAA60011BD321566F2C8990996B662C5D12F1CCF5304B400E1FA7E496BC63DCAD33C3A660173DA466FB2879979453C89D81A672A4708954C1662337050C4A62382CDC4A02CA52CE361C66ED9A8FD0075E908B062AC2F12905819905C08CCD223B0651663A43C980CDB6568010A85D25FC9F4921199670AE34C89A2A926A65D4376350935BF0162FB035CB6A64DE199B88BC2E49D1B425CF0F27AF6968E6DD5BD51E4D6A494EEC29A066736462738721733AF9999FCE2E64D4078783A015F45F74AF20550081A01D81669D3EC84335E80BB367DF9298E084E16EEA5E444BB0554403D900D2DC320F9DF999E57E36122BC2E14950111D146D2C3BB78481DBA632EB346468862E44F3D6C433B8097BFF0D295258243502309B8A5DC0E75F487E9789675966B8DFEA8D513D300EA74CC7C9787D4A7AAD9401FC1D8D9C6 +ss = F68927D6306B93CC1F822E2CBB5C43B3 + +count = 98 +seed = DDDCA9DC31BEA737D3F474E7560B37FACB2F53C803E768FFAADE7669FF94B1D4FBD17068CFFD5DFDD24AADADA4EF6B12 +pk = 5F5E6BEF94BC0012EA7D7558EF4EFB72C137EFE6B14562E0C5F3BE819D7D5809C332F5E5007D3B7992B92719CE077CBD4DCA38FBCC4C0190AB60D8016AE2B4DDDF9ABCB58A3763B3A45947EABDB9A04271F94A0D17B364B854157F3D155D85F7F7C8A171BE9B2373AC90F3C34C001E961ED2CC130ED884486760EAE9156FE69FC0959C9FDA964D212DD304EEBB18AAE58B5D253997794B675AE8BBFD98777E7634696E0E01E005113DEABDB23404FE8D7CBD180C6B0FC0DFB6A995FF3FD2F962DA1FCEFB1080B373E0702FA46D602B7C0F838D6FEA0F6FE948E44201AAA0854135B694547C688C6A1A80809334E321CF47B8FBA421877EB562588E4717B5D1835F6B81A539F8173A300BFF53264A092D110E00B4C4058028EC647DA3C8BAF90520ACD123A20D027E2952A1A45AA892948C84E3092985F8A49293DB7FB98869704A6E8E6827B7C6F20301 +sk = AA6DD1E5799CDF7AF9C4FC632B3EB9D5068EB2D3B95AB779EE1275C14C5AF22568E19CE77BC30BF50CD537005F5E6BEF94BC0012EA7D7558EF4EFB72C137EFE6B14562E0C5F3BE819D7D5809C332F5E5007D3B7992B92719CE077CBD4DCA38FBCC4C0190AB60D8016AE2B4DDDF9ABCB58A3763B3A45947EABDB9A04271F94A0D17B364B854157F3D155D85F7F7C8A171BE9B2373AC90F3C34C001E961ED2CC130ED884486760EAE9156FE69FC0959C9FDA964D212DD304EEBB18AAE58B5D253997794B675AE8BBFD98777E7634696E0E01E005113DEABDB23404FE8D7CBD180C6B0FC0DFB6A995FF3FD2F962DA1FCEFB1080B373E0702FA46D602B7C0F838D6FEA0F6FE948E44201AAA0854135B694547C688C6A1A80809334E321CF47B8FBA421877EB562588E4717B5D1835F6B81A539F8173A300BFF53264A092D110E00B4C4058028EC647DA3C8BAF90520ACD123A20D027E2952A1A45AA892948C84E3092985F8A49293DB7FB98869704A6E8E6827B7C6F20301 +ct = CA1221AE3B6D2227DBEB2D3366A6FF04D4CEAFD8A87A646A0E69C17DE92A65FE381542CCC3DF59EE06EDD5589252CE0154D00CB22BDE00426BA25F63E4D80872B0369562226670F392ABC3EE8254B777AFA9818DA03201D927C6A44A798C4E8101DF0A4532439592FF6219230500C7BA12B97300F7E8251A15508E61299AC293EE92F07C720E5647590A445C11B746402E7722B801ED9D237C5E11F40EAC9F518BB17D2C014A45AAC78605365D21191A0176DA1EA59002F6552A84B34E9CD87099A4C92682510E0F306DB57F65A8B22BB4835EA77F71345041451402F7C5B8C5254F64ECB9E70694D6942986AB2CE261E8BCE34DBAC5BC35AEDAAF97F4638468E81A58A86762F3C7DC33BFE134F7EBBA728301704D894ED7B1E1EE9B56FDC3BC28C991337265D84811A47351F6AB7B7DC13F5903CE4C8533E67EB4562BAD582B6F37A1E43FE31420F901E066D6103DB5DDEE5402CBBCA607DBDC +ss = ABB141C9189DD1D2F5BCD86C02037C36 + +count = 99 +seed = 2A6F7386B815366F572AEB6C79E272CC21B7095FE09575F18072C9D677DA23BC9C8A4BC393B7524604D299BEDD260C8B +pk = 867436C365BC16B95C51E7F0141842F0BCF468592D95294141E6051F329F36DAB2F22FC2C76ED5B66CDCA197D111D7BD9E78EBF1D52E02770B91B6BE2D4BA7D895906D72F7DDB7667C41691EDE3B153BADE39B7873F4772264249EDDEE0FB5A78C7AC439CE9668E231C568C44B004292F96CD47AA8EFE07746AD6E40075D976BFB75BFC481D94C210FDDE78D3371156DBE081064F6274DDFF1F9BE05BDA76886345AAC5F005C307D9A2F2C3DCB6E16EF29530BED4D583DE8507AADC01F7C364DBCF11A1EE94588BC6EC6AE9C23835080ACDB0DCCB33B73A400AB9101111649F226657F153C58C2067A963173A955124AA33334E85F1380830E859EF99EEE2994F4CF9AB19EE0F8D426FA774D4F36A17668870051C1445B987A0034B16F76329FE7E3927E39FEF157C082212046512AADEA51EC22BA069B4684A939937613FC581E9B7596EBA0088B8000 +sk = 195D6C86A3DF4C21E3007D7F2768B43CAE7EF2D029CC7ABAD98E68D0374DEFC5F2EDF8EDAC8ACA265EF84900867436C365BC16B95C51E7F0141842F0BCF468592D95294141E6051F329F36DAB2F22FC2C76ED5B66CDCA197D111D7BD9E78EBF1D52E02770B91B6BE2D4BA7D895906D72F7DDB7667C41691EDE3B153BADE39B7873F4772264249EDDEE0FB5A78C7AC439CE9668E231C568C44B004292F96CD47AA8EFE07746AD6E40075D976BFB75BFC481D94C210FDDE78D3371156DBE081064F6274DDFF1F9BE05BDA76886345AAC5F005C307D9A2F2C3DCB6E16EF29530BED4D583DE8507AADC01F7C364DBCF11A1EE94588BC6EC6AE9C23835080ACDB0DCCB33B73A400AB9101111649F226657F153C58C2067A963173A955124AA33334E85F1380830E859EF99EEE2994F4CF9AB19EE0F8D426FA774D4F36A17668870051C1445B987A0034B16F76329FE7E3927E39FEF157C082212046512AADEA51EC22BA069B4684A939937613FC581E9B7596EBA0088B8000 +ct = D170E6E4C5D4540AC2628029CFF149B7F0CDBCA679EAAD94357DDB9AB0C2CD0FF42C0FA0B7C74C4C3FC39D6CD3CC7919CB1053CC58E9008C9793A8098304B2EBD814ECEDC8740F199BF1B4A05B64F4E70A76B4640330ACED9967416226A7946A1C18C433F0C260B1B4FE5E82F800082D86B188A477CCB81B0EB7D18AD006378B28684A6D479FF53B66F3E20C597A5AB93E978EAD97F3E4A62BD31657B1DDEA441851B71A022066C2C3FE1A31E36BCC22F60C12E5B6D4012879A88B39CCB914480CC30F1489140CA9A9CA54DC2CB635E450A0E2308B1EE20DE8502602C744968E57841BCC8F62B0AC14EEB35ABC77BE42EBF33AE0EC3E53FB62EF6058F6CF27DD91D26CC9EA1B8996F35BD800E15928C7318D0014E2A29706E62A8AF0FBB8A2512823A09E4AF327234ECF4086DBA31A8B26E130633256C19D0BAA5244D3DEB6E397E6B2058DB40BBDB700C58C6E1664620548D2BA2F8702E95878 +ss = DA40C7AB4E2ED76E4A3BDB509B806E5C + diff --git a/dh/sidh/testdata/PQCkemKAT_434.rsp b/dh/sidh/testdata/PQCkemKAT_434.rsp new file mode 100644 index 0000000..5f969bb --- /dev/null +++ b/dh/sidh/testdata/PQCkemKAT_434.rsp @@ -0,0 +1,702 @@ +# SIKEp503 + +count = 0 +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +pk = 05279D27FF7E3A38ABB05DCFE23B5831C030D832D3EAE35FE06A6538597532D22A0F4012FB2263E160495F8291B58D9DF8A8947C7CF3E6735520BB2D094912408829851AC4B85AA922069F2AAA0A4827DFA4730E9CF05485CBEE411C3D5169DD4953746B6A2E6574957EF920596B1612BE62A883740B5A0C157117AE1C3A07E4CE8CCCE7E9E88FE7C20A507FF019AE0893F34303E173D291F6CB7ECB4C3901FF34A48DE40771F5BAD72DA2B4C1CFD0A61F33E39327A8DA60F5640D4C2E71EF9C7297A4E9BC50493E3BA65D3664610A6D61035CB6600378D017D1E1810ACD113252D60F5915749C2B5CFB4452C40C86F1F40C63297DCCA900686F2D2266F9444539D9BA13B1F52FB2FC3BD4F3EDAA6EB707AAFCA5261EA271ED961B2ED195D5E3B0299179251866CE0EAA31C5C90B7999A8D63BA2DE84A8AFA19F11F2DC0CACA39B982CE053F71D269931D9EE26BCE592A8EA818553BC8F8D244F62FB4F5E5386E3EFF5CD231401C9EC2BA57FF42DC3B3791357A53E1E31394008 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148038626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB0F05279D27FF7E3A38ABB05DCFE23B5831C030D832D3EAE35FE06A6538597532D22A0F4012FB2263E160495F8291B58D9DF8A8947C7CF3E6735520BB2D094912408829851AC4B85AA922069F2AAA0A4827DFA4730E9CF05485CBEE411C3D5169DD4953746B6A2E6574957EF920596B1612BE62A883740B5A0C157117AE1C3A07E4CE8CCCE7E9E88FE7C20A507FF019AE0893F34303E173D291F6CB7ECB4C3901FF34A48DE40771F5BAD72DA2B4C1CFD0A61F33E39327A8DA60F5640D4C2E71EF9C7297A4E9BC50493E3BA65D3664610A6D61035CB6600378D017D1E1810ACD113252D60F5915749C2B5CFB4452C40C86F1F40C63297DCCA900686F2D2266F9444539D9BA13B1F52FB2FC3BD4F3EDAA6EB707AAFCA5261EA271ED961B2ED195D5E3B0299179251866CE0EAA31C5C90B7999A8D63BA2DE84A8AFA19F11F2DC0CACA39B982CE053F71D269931D9EE26BCE592A8EA818553BC8F8D244F62FB4F5E5386E3EFF5CD231401C9EC2BA57FF42DC3B3791357A53E1E31394008 +ct = 100692A8BD30F01BE8AC6B1AF8D93A060D3821B2587F4038D64B72426A194BEDE63CA60B75A5C3C15532CE307115AA9D77AC232E14D99C1E1AFEF1EB2D6321AE342F990023466E683A2568D59A14325C2C6C272029741D8E36976D1804059BC06B802F3A495EA50D0DBBA93FD263F4CF30BDB5F783BA6A0775715B05F700C85B316F7AA1A1624973885941DBFF91316BF47AC698E11D6B2418F553379D67A00F784B8643FB8A94029584391D488775EB4414A5E6E8122B0F282D900F3D05775F1DD994FB232ED826106203CD3433967F60FF925DF9E86CB376CAB5FD90B132E425682741F6AF078E75792CB4CE085D44993CFB6A4ED5AA3541640A0A67687922B92382CAC47C6AD358011A269CC7C17CE651CA2E2393F7DFE19D7054FEF69610A353D676B1F076549510590D406AD13F4A3292CCF206DBDAE47F08D448CC006449F27C1FB54E9C9E6F16ED2F3D120DD5AA2620D76690F00E31904C601310C76A843A58E1AEB9C5F515FCEC482C08205FDE99A89E64485EBBD43EEFE2E24D18EEE8F20DF6E113C6667512E28396862C98F5C0 +ss = AF1280151C2C59B4D4150B18BA7F71590523CEA83C9BDDDA + +count = 1 +seed = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC81ADDE6AEEB4A5A875C3BFCADFA958F +pk = CCF655D6C656A0A80533FAB834B61B0FD8CFCB681966194B4AC63D1A9D3E607EE72A929EA6EE3C6FAB682E48A84127C9DB773B0728D8583E9C0F349E7E7A3B0E9EFA70AC8AB097853D8143ADA5804DE75DE0D7C4975CA91573C62F3060D9213F1EFC82400D167252C9E3A22259E1D4988724E2B73FB40D8625FD0D90DD13062CCD8EA37D2272CB31E81C9E0B8A79E99A7C1090CD7F9BAF5DE30DC044BEF38957367119357EBAA5466D641F31288C06B895CEB1E51B893AEF0226B02115126CC526330008E8288BF9033C4FCB7615A4B53BAD2D731C93CDB26D28AFFC51827CABCBB5544068DDE49DE5E52F235026E8FBA3BED35A1215332F2C7E9A01F9363B3529BFB89AA9A04323C7E0A5E03AA9882E0148BB8F0A700B62149DC5CF4DEBEAAAEFA67F42FF66B803F9E6BA74E04CA273DBEF6212C40FEAE361D7260ABB1397B250C15CE7D92C1393E436FF82DD1A00AA3F60BEB35D0A1AAAFE3E1634730E4364C625815BC6BCE2D6A0192F9B07FCF665AE70D7E5BF1A760DA903 +sk = D60B93492A1D8C1C7BA6FC0B733137F3406CEE8110A93F17003271531CF27285B8721ED5CB46853043B346A66CBA6CF765F1B0EAA40BF602CCF655D6C656A0A80533FAB834B61B0FD8CFCB681966194B4AC63D1A9D3E607EE72A929EA6EE3C6FAB682E48A84127C9DB773B0728D8583E9C0F349E7E7A3B0E9EFA70AC8AB097853D8143ADA5804DE75DE0D7C4975CA91573C62F3060D9213F1EFC82400D167252C9E3A22259E1D4988724E2B73FB40D8625FD0D90DD13062CCD8EA37D2272CB31E81C9E0B8A79E99A7C1090CD7F9BAF5DE30DC044BEF38957367119357EBAA5466D641F31288C06B895CEB1E51B893AEF0226B02115126CC526330008E8288BF9033C4FCB7615A4B53BAD2D731C93CDB26D28AFFC51827CABCBB5544068DDE49DE5E52F235026E8FBA3BED35A1215332F2C7E9A01F9363B3529BFB89AA9A04323C7E0A5E03AA9882E0148BB8F0A700B62149DC5CF4DEBEAAAEFA67F42FF66B803F9E6BA74E04CA273DBEF6212C40FEAE361D7260ABB1397B250C15CE7D92C1393E436FF82DD1A00AA3F60BEB35D0A1AAAFE3E1634730E4364C625815BC6BCE2D6A0192F9B07FCF665AE70D7E5BF1A760DA903 +ct = 3088E00719F21017008052B1332C52277BD0135C86E293270611599BC5787508972B82A077EAAF851557E331B32D75D70AFAF9C32E142A8864CA8F4E1909371620164ED231B9F7B711F6A970AF8321625351215303C617B783101D13DE7E0D64F100FC4A1E11414123BFE461001F03808BF95B7DAAB3BDADA5C193A59E0F9FDFA1A40CCA4FB2929FE0302443D4C2B3708A8A52673C9CF7EF5131456E8EE123938C6C0C80F6E1B8703E6FF885BC110438A710D229D0BEDE280F0497C61ECE61F8C1D11C163F33E034E05368FDE4D9C76DCCC8AAD665C2BA81F0132A8016B385768C80CFE2A49EA093F653D3304C0767EE6AE94B5B3468FB675D371C31F72DB05BF2E40C5DF101288DB11FB32449FA6E9716342E0B547371CD04BA035C1F824686E5CEC119B218AFE37FAA746E9E4083C262A04E61412FF1E9EB29362AAE33B6662A4E338BB305FE498E6685B06234F5497AD4105D476A57843CC29290AE082AAEE4A2B294884CE7857917D3F9E0125B97E2095DE8341019F9990EED947FAD9A47D634AC907920357DB28073BDC39D3764C998 +ss = 810D3549BEB3DD6E45EEADBB75386F6A63FF3330ECB04C22 + +count = 2 +seed = 64335BF29E5DE62842C941766BA129B0643B5E7121CA26CFC190EC7DC3543830557FDD5C03CF123A456D48EFEA43C868 +pk = E18612D0598700639858EA9ED63F644ADEBC7EB1A7FF24249157F928ED9E32C54A60120D63C98F610550069F160E0DE97A555C0810A963826A3E097768B102ED61DE243D9DBC698E319C271A8CA84BE6FC03EEE068145F828BBE53BF58D3EB296A77968765DE63B6F413F6548981A623BC411857B867DA3CFECB227ABC243BBE8783C787171B6EE8F089DAAE7E47A42970D3497F58AB596063CC7C6B37F39AE4B50F16157A456E9578F4C4C15DD81F627824CB5FA23830574F42317F055B6C68B7C47221D7BF66F935AEF1C8BF4FD621BD8932840FE2A1C62DE65BF353E8D5A7206D46B1F281F8828B96E171AAEDE31873E1C49569329B98701E39336B8A1A11937CCEF0F78BE88B470B26A1491C6F6AFB9E12638B0A69BB8E2B575C9A58E6256131EC4901CE345B5B6F6987B477D11407C6755A0D3C29CAEBD61A626D30BD86A7DF57AE44D1A8E460CEED2028F9A295D4F4480D9932859A8405959A36C482A94CCFF5E0CFC28E3375113656AE7F538A46BC5F041F2D5919232B +sk = 4B622DE1350119C45A9F2E2EF3DC5DF50A759D138CDFBD64E82FCC97CA60CCB27BF6938C975658AEB8B4D37CFFBDE25D97E561F36C219A0EE18612D0598700639858EA9ED63F644ADEBC7EB1A7FF24249157F928ED9E32C54A60120D63C98F610550069F160E0DE97A555C0810A963826A3E097768B102ED61DE243D9DBC698E319C271A8CA84BE6FC03EEE068145F828BBE53BF58D3EB296A77968765DE63B6F413F6548981A623BC411857B867DA3CFECB227ABC243BBE8783C787171B6EE8F089DAAE7E47A42970D3497F58AB596063CC7C6B37F39AE4B50F16157A456E9578F4C4C15DD81F627824CB5FA23830574F42317F055B6C68B7C47221D7BF66F935AEF1C8BF4FD621BD8932840FE2A1C62DE65BF353E8D5A7206D46B1F281F8828B96E171AAEDE31873E1C49569329B98701E39336B8A1A11937CCEF0F78BE88B470B26A1491C6F6AFB9E12638B0A69BB8E2B575C9A58E6256131EC4901CE345B5B6F6987B477D11407C6755A0D3C29CAEBD61A626D30BD86A7DF57AE44D1A8E460CEED2028F9A295D4F4480D9932859A8405959A36C482A94CCFF5E0CFC28E3375113656AE7F538A46BC5F041F2D5919232B +ct = 4BF036711DD1C3B4C941967D4F63A35C4EBBF45E4601573CF33D49921D95F17792674F7C18E455D8C7F1BEF479BB91D5B22E2EC955988C70DFFAC371BFB41AB81252F22949685E78E055E7495D82AE77006B1D05015F149D9EA4F927096500C8FCB583452C2E20E0C55B4AB18F801E570E5A8BBC56273902279B2B4C3C1DB0DF7811617694C1DE0117A9E112FA58EA523F8A40A749184DC9F9EF44E09BF372EDB9D55A4C7DB348EC971185EBE8CD005A73008ED74131AB939083813129086BBC1EA1DD04A3D5D844F901DC9FDF089A2504F1D32C61EAFFB0B0B66445856AA5359D49DD737B01A6235B2A35E29154AC71229F93DD4C9CD3DCA2C3621158F11EC6895D5C57A6E2FDCD0DCABB4E150DB2ADF9F5F16320BCE723220522E05B196AFBDEC21FF14E53FE9EF054639FC98D637FEF20FA0149709517BB3521C787B9F377857DE2B41F4FCF60113DE4E0488EFAF0A536E8C46B34E41D8DB237AD704CE981D15CD8765084B35983BD35E172ED977F9B43F8D9273B915D8639F91164642199EFC3F90B43017D1D46BB68ABF28A7EA1D471 +ss = 68CFB6A6E01FB2FFD8707C8278D705E0DCB53A502BFAD6B4 + +count = 3 +seed = 225D5CE2CEAC61930A07503FB59F7C2F936A3E075481DA3CA299A80F8C5DF9223A073E7B90E02EBF98CA2227EBA38C1A +pk = 6D839375DEE6F1486CB7072A4994BE428F1AF5876B5D34943BE2D1C20F650D528EDE5A453CDDD87E83D54F4BF88A13189FCC1ED8FC8E11DB8ED98E0BE87D2E778BD06B33214CE15E5D62554B0367BBA720028A40E20FAC9AE4DC98326178E162611367A51EDF011FBC621492E6EC235FA5CFB604C2C976B8BF8CFBB43D37B26E21766519E11B658D6706D515E4B288E2337BD7A56BB6D51535CA467BC6A5D495884160EB13B7DD6073091A7602C0D2CD98873DD58761603A85CCB85A3A032E25E4BCD2AA384AED7AB6341C68BC125DD49CA7795D7060605EDEEF5A511116BC2E4BD545143D6791A632F5CE045FE567DD45778CF4A297CCCC75E3AD174C3A3DCBB44FAE1B7BC692194034D102C2AC8B7D05E94F63BD297920A35494778C4AA37A8F22F9C6A7C82DF824293FBADEE6B6F779C32D6AA17396ED94DF2C1B2ACF5F979F4153B7F38B841775B4D9E1E02C2E0DA524905483D401C6D7200F7F310A362DBA67B0C604FEDE8E17AD0C255B4811A234DB134E5E0424518118 +sk = 050D58F9F757EDC1E8180E3808B806F5BBB3586DB3470B06DE950541FD53A8A47AAA8CDFE80D928262A5EF7F8129EC3EF92F78D7CC32EF006D839375DEE6F1486CB7072A4994BE428F1AF5876B5D34943BE2D1C20F650D528EDE5A453CDDD87E83D54F4BF88A13189FCC1ED8FC8E11DB8ED98E0BE87D2E778BD06B33214CE15E5D62554B0367BBA720028A40E20FAC9AE4DC98326178E162611367A51EDF011FBC621492E6EC235FA5CFB604C2C976B8BF8CFBB43D37B26E21766519E11B658D6706D515E4B288E2337BD7A56BB6D51535CA467BC6A5D495884160EB13B7DD6073091A7602C0D2CD98873DD58761603A85CCB85A3A032E25E4BCD2AA384AED7AB6341C68BC125DD49CA7795D7060605EDEEF5A511116BC2E4BD545143D6791A632F5CE045FE567DD45778CF4A297CCCC75E3AD174C3A3DCBB44FAE1B7BC692194034D102C2AC8B7D05E94F63BD297920A35494778C4AA37A8F22F9C6A7C82DF824293FBADEE6B6F779C32D6AA17396ED94DF2C1B2ACF5F979F4153B7F38B841775B4D9E1E02C2E0DA524905483D401C6D7200F7F310A362DBA67B0C604FEDE8E17AD0C255B4811A234DB134E5E0424518118 +ct = 2310AA9B6DED40FAC980646C368ACDF8263AB65B5262CED6EFD708222FD5B133EF6EF22A56B940228CA115BF7A9021454467F35FDACA7FA185D3704A4AC630246FA53B2A57FCD146BA8761853110BF380C6B3EFF773B81C941C4258F32C5E392E1F2E4BBC36C0D483AB7CFEECC2679B35A06C50FFD0D9B6C3299C166002ED90EA16030A95CF1C3F1F07B6B7F79FE286FCD2E9C23B95878D48A841F588858EF235B05CB06564A8083ECACFF091A179092AFC512BB652F9128C2C32A462570BF8BD59EA43EAEDCB0E80EB4DA4FBE82379200DCA2ADE33E0168ECDB06EC57C4564946A4BE1D07EE1DB50A05445E1C1274949EE0E3E0444EBC56F7737A275F9B3CD1ACF5E24C96275D9BE24B3846AB7C9019AB51BEE384FF0F0B7EEDBA3FAA640425854478C4D03FC710415880FA6E05F7D39D6ADAF8D781BB71183D0DF40FE456ECA30D789E8A97D271D59FEA9152E2C31898EB6272AF8E9022476FA21193971DBCD7F92F0A2984E3DC16FAA1AAFE85B3A9B935ECD3D6E9D25506265D2F9B7AD4899B5BA812EDEA355CB03C8E220782405079AA +ss = 6CB10B8CF5C9E4D96562A962E5C1B0553799BCE28197C48B + +count = 4 +seed = EDC76E7C1523E3862552133FEA4D2AB05C69FB54A9354F0846456A2A407E071DF4650EC0E0A5666A52CD09462DBC51F9 +pk = C4C97E7F806E15524BA63CE182DC0838B3056E17880565D4EA4665FEE04333AC3C2107C358D4B472F431A19EAF8A336AE7EE591142410A446D41397DFE653DD456824288B7772B9A0E697384FF67986F60CA04AEC1B07032483959F7B32C1F90E1CB538182F796A8B0BDCB639EC7B5A963CF4EE2F988A1DD96CDCDF89233E97A9B1387F3B607498AC9A6AD3C3B12D5984DEF61213BCD11178C061C61CB18DC2F28A984388BC01C4160FBAD75BDCAEDD670614AA17C5A909A1B7A3EB70399CE79BBAC2A44A84C65AAA2BC0C5C1B9A4F89940AE3246640B55E050370F73C26151FD67D8B6FB3C467CD2DF3DC15DB35963FA1A3713BB915CA93A9B2E730F0D3FB412F96BBB3CB3178BFB79C6CAB3411068C31612164FE0FE12423E7E48AAE429C98BF85E80F5F7E6FA7BACFD69E7ED873C168695F9CD89926EB29A40CABD47477B01FE57B992B870E510E29E063DEA9097CB15DFD842D05AD36C34D9967DE9DCDB6DF80F8E47F67C64D0D38AF185B443A08DB897BA69F6F4CC2DB2E +sk = 66B79B844E0C2ADAD694E0478661AC46FE6B6001F6A71FF8BE2D3C64D38269A1EE8660B9A2BEAEB9F5AC022E8F0A357FEEBFD13B06813804C4C97E7F806E15524BA63CE182DC0838B3056E17880565D4EA4665FEE04333AC3C2107C358D4B472F431A19EAF8A336AE7EE591142410A446D41397DFE653DD456824288B7772B9A0E697384FF67986F60CA04AEC1B07032483959F7B32C1F90E1CB538182F796A8B0BDCB639EC7B5A963CF4EE2F988A1DD96CDCDF89233E97A9B1387F3B607498AC9A6AD3C3B12D5984DEF61213BCD11178C061C61CB18DC2F28A984388BC01C4160FBAD75BDCAEDD670614AA17C5A909A1B7A3EB70399CE79BBAC2A44A84C65AAA2BC0C5C1B9A4F89940AE3246640B55E050370F73C26151FD67D8B6FB3C467CD2DF3DC15DB35963FA1A3713BB915CA93A9B2E730F0D3FB412F96BBB3CB3178BFB79C6CAB3411068C31612164FE0FE12423E7E48AAE429C98BF85E80F5F7E6FA7BACFD69E7ED873C168695F9CD89926EB29A40CABD47477B01FE57B992B870E510E29E063DEA9097CB15DFD842D05AD36C34D9967DE9DCDB6DF80F8E47F67C64D0D38AF185B443A08DB897BA69F6F4CC2DB2E +ct = B13B1ADBE980C3D0DBEED0243319534E8D8C5AEB0F775446F83C08C8CD667D9BA0A9E3AFAC556045C3A38E1E7A6BFA9821275917170EB08D6E9B0A5050321E8FCF8DCD4F39B1A04FB08ECF5C7612814704395AD82B7511512CBE659834CD9FA4B79B84C18489B4B05AC4511A7E3EFF4149CB91F63614A96D0E5B13118730BA384518001F4BA0998C83AA09F336900377FD29FFACDB44DFFEACC680C3AF2C412D9D98D8F4E191F5AAA95D7B6EEDED0D025B6E55FEB13B4EB45D1FFF532140A02755963742B6C7E1CD8EA4917431BBC201C632E94AC560BCDB4BA0A9E59738E4706C78EA619EE7FD6480ABF52FA0D3A8494B03E8E4B85E8344F926E820F42A32C716147A0594424D0C63E0EC033E69B97B61E6F746635524094CBE1AA716B239F284381FAA0F078E743CF8F94DE6C00ED2055610C1A64ADC738F03034867CE0B9FB14CA9349819FF11E66DA946FEBBFF934632F556B11081B8B4AB6A8E7820172B641E9437EE61C1D47B9CE281A52E842C5E0068B51D72D2917E2E676FED343E3B13E7394D502F7A744CD2D678402B0920F443 +ss = 815FA89CD9C0C6DEBD6D4C3F4B38FDBA423C8AE4555C6939 + +count = 5 +seed = AA93649193C2C5985ACF8F9E6AC50C36AE16A2526D7C684F7A3BB4ABCD7B6FF790E82BADCE89BC7380D66251F97AAAAA +pk = B1EA55A82BD335EAD91F9242F35213F5B9F49400E2D7AA0CC3491DACB960172DE119BB65CC0A782FD3290590D3604F1DB38AB5DCA5FB8CC01621FD21EA192B133E3B442DE7B1DF9E3C403DFCE43C023EB5DEB435F9D1BF00C6F3A923CE8A5993C377BCE6A96EBAB9904EE4D27644CF3F3566C3447C555B693A921DE2D41BEC1A04218FA743844EC770B340CB25AFE1E68A9401829A858661745990452E2CD02489DB2D4948EE47EB77CC84CB45364BD877F9246BC1201C57D5A6D4771E004013FE0EBCDF9CEB597EDDD8AB968812386D2804ECD968DD91F7B764679E081082A7A4E855FECFB134EDFF1112A286C504170454FBE64B295682561DDD329A4BD9A386B07D7CA06F4A24FFD6A6B290A24377206928997CED46975B400D9B1F52DC3272A3638CF1A03B7837FBD07ECA3A03E9B87D9E48AB94B53DF7D13F78FF48DAFB3615345716623E3D34D06A143C7D6D8E6D1E0CC3C064DC2880A2B39B1AF72B2F89B4D66A65C2EE2E539C862F1F836F8E2C3E731ADA4A2807EF31 +sk = 7EC408F52C9AA723D0C41D9987682A5F4CE6C9DA7CD0215AA08CCF451B049FD51D7A9AD77AE14A81569DF8C9BD3A8F1EBEA86FDCFB823002B1EA55A82BD335EAD91F9242F35213F5B9F49400E2D7AA0CC3491DACB960172DE119BB65CC0A782FD3290590D3604F1DB38AB5DCA5FB8CC01621FD21EA192B133E3B442DE7B1DF9E3C403DFCE43C023EB5DEB435F9D1BF00C6F3A923CE8A5993C377BCE6A96EBAB9904EE4D27644CF3F3566C3447C555B693A921DE2D41BEC1A04218FA743844EC770B340CB25AFE1E68A9401829A858661745990452E2CD02489DB2D4948EE47EB77CC84CB45364BD877F9246BC1201C57D5A6D4771E004013FE0EBCDF9CEB597EDDD8AB968812386D2804ECD968DD91F7B764679E081082A7A4E855FECFB134EDFF1112A286C504170454FBE64B295682561DDD329A4BD9A386B07D7CA06F4A24FFD6A6B290A24377206928997CED46975B400D9B1F52DC3272A3638CF1A03B7837FBD07ECA3A03E9B87D9E48AB94B53DF7D13F78FF48DAFB3615345716623E3D34D06A143C7D6D8E6D1E0CC3C064DC2880A2B39B1AF72B2F89B4D66A65C2EE2E539C862F1F836F8E2C3E731ADA4A2807EF31 +ct = 9C17973667EB92132A299CD857FC15B7FB00876BEC0D55E030F375315EE3A1753E1C325E18F16A814F41F97D12CCAE77B81B613A317CB6F8B819F727E879193B7FB4F9FF27A07BC4E411A86B38197A01A860CA7093C774093F2C4F3A037CD7411E3ACF7776D075B0E44D7323644DE236D33F6BF31FDF94398B07B0E1812B01E7923555209E8C9C7DFC9BB62869DB73FFDAE16ADB5267789F2E1F57C8BD4D4CCBCE822730F37C6D9693BB4B3FF8F67C38934DA5E22347D1115F612E542C33A24D8300F4A2C3CBA9B8832710F8B066CAEC61F59B9903FFB6610DCFC04A4AE9B2BA8525AEDB16FDFAA74FB3925AB4B903B9DD8317FD1B219F5761F0540667205D6F838062B5A3BE2AC8D18326060E4DED3BB5C09CA0F6612B213FEB5407AF7CB210A5101B3ADDD28B5B6F66D4A660F0C678158EC73F5DA5BBB2EAA01700E50B95B61B93258BE34ABBFA7168A39A5B728A8983D08E187FABD79A4F35BC4E850B510CCE31356863F81389801C7E1780186A18CB187114B958F450A1209E85179AA64E4D196FD5EF8ED1A317152FCB1FD51323AFB4 +ss = 4668C26A46478B62B40E5BED0BF71492A7FDB443FC010AB2 + +count = 6 +seed = 2E014DC7C2696B9F6D4AF555CBA4B931B34863FF60E2341D4FDFE472FEF2FE2C33E0813FC5CAFDE4E30277FE522A9049 +pk = 4B8C0E0261C43AE34A19A0C61C63C333C8CC58E415944FDEFED6A7AF831740BEB8BA07E79C806CF4DA9A1DE9448F657F71E0A05C0AE67C0243E36BB4A0560F0F08BC79BC60A32E66B84D9C8D3BA2AE66B7B6DB17584647D9B412DD25219D3F52CD939E8B29FE13458460A22D9EF857DBCE1C41E84796BE1B5653DD37660F57C76419688DA976A1D42D53357F42A80BE16B74F289C1EA06D9410A3E4AC94FABF1A05FB87CD0E3233B469E32CF98500C8FB92C52743A4923D83370AE8509ED2C24F05A3B03EAB4D6AA7795EB3AF2F907E06CF0EFCEB2019C6B6544F0E9B075C438BB0433669B5EAC9010733ABB675ACBA6A3DB1E0EDE690DCD3CDE4E2B17BE9C0B26411E9CD7C5C06B18150DAB03D7C38CE09B4FBFB64827FAFE6C7E62E19C9477F73E1CA00B0A737F3A8CCF6D669979DAAEE8B445372C147790D420DD53630B87676B53FFF90242D834125A1A369975EB3475716CC7B9E168C4A9560B364F164E6EDFE67DDC1967C16496C339789D22C757934980C39752E10E1D +sk = C121915BFEF6ABDFC177DAE2F5A24218F9ABDA2559AFC67484EF52DB5EAA6DF8EC3A0BC5FFA730DB0DDE8C5F38F266D5C680A78D264A7B064B8C0E0261C43AE34A19A0C61C63C333C8CC58E415944FDEFED6A7AF831740BEB8BA07E79C806CF4DA9A1DE9448F657F71E0A05C0AE67C0243E36BB4A0560F0F08BC79BC60A32E66B84D9C8D3BA2AE66B7B6DB17584647D9B412DD25219D3F52CD939E8B29FE13458460A22D9EF857DBCE1C41E84796BE1B5653DD37660F57C76419688DA976A1D42D53357F42A80BE16B74F289C1EA06D9410A3E4AC94FABF1A05FB87CD0E3233B469E32CF98500C8FB92C52743A4923D83370AE8509ED2C24F05A3B03EAB4D6AA7795EB3AF2F907E06CF0EFCEB2019C6B6544F0E9B075C438BB0433669B5EAC9010733ABB675ACBA6A3DB1E0EDE690DCD3CDE4E2B17BE9C0B26411E9CD7C5C06B18150DAB03D7C38CE09B4FBFB64827FAFE6C7E62E19C9477F73E1CA00B0A737F3A8CCF6D669979DAAEE8B445372C147790D420DD53630B87676B53FFF90242D834125A1A369975EB3475716CC7B9E168C4A9560B364F164E6EDFE67DDC1967C16496C339789D22C757934980C39752E10E1D +ct = 30E7FF26E92C4A2D2C959284849698CAF358F6FC489FBA3CEA03824B78C096A337486835851ED787C200C0D4774E5F894E3B0641D999F6C5D15BD1A9346F270ACC72A0C6692D9BDB4593E1A8F17C493A55AA39CF2E1CCFFB231DBFE77E6007D96E742AC1DC6C4CEC1253F2100A04C53736D0827850F725CC885D3912EB3C28FC808AF5F441DF8238E3F8A9899673F32D2BA0C523DBD7C0BF50297765612220A1CAEB971A3F6D948D6268BA0BA0A84BF5E30EFF97D834BD08BDCC456016075F5703855186230281E2FAAA77360478EC5CD9E2023717A8DBA18DD0BE7ED6BCD8D8E9D46D29597DE71CE0C97344D10331CA6D7F68A5F16E6CC0348EB6325AE178F4FCE390FA71F7DAFB8A16D26DACEC6793D01793BAFC6BBB7C31A77B04C5C47D0CF150D60F04633CCB7481A738632E012A035C1B6F880068697BD7251C68D708C60DFDC29F0626DCC54459044607C2AA57CB2B0C962E507B134367BD4CA3C451BE14B2DF5227D88AF093FCEDE18314F733B7A177D465FEBA54453E678B4E4809C4E2FE3529AF3C11B85D30F288EF3C332ABEC4 +ss = F9CDF2C113564143F3CF1EF59E20785D99974121A6832AEC + +count = 7 +seed = AEFB28FDD34E0AB403A703B535296E3A545CA479C1D8148E2D501B3C8DD8B1034BD986F13F1A7B4671BE769359FD2AAB +pk = 6F0C726DF1330754839FECF6CD5712D0EF05C08FAD2C1CBE3D4F90A207287DCE085844C86ED3DD6184D993BABBC6A5D87DE99773F52A3FE76CE2264D6A53243D976C7F793AD39E34A2971CC7ED240AA9A4D8BF959BC12456138B39A8A76223E28E3820F5C216E696E317644E8D7599C7EA9D3F1996D2B85B6C398B5E581C59E08209E53D956BD92469FBB9DF66AF0B50099CD72FC6B1E451D4B867D84A8BD3A0702C2452FF35DA3C0F051B80F68633B3030CE57B55E8CEB068E80B6C1EFE8A52665E29323CC87D942FC055FB50799BD5378BF0C2EF157BDC49975A5D334CC5E718AE4649D462291C2BCB3A3F984054FB2665E347968029AD7931BE1A60C305792BB9886D5B46E4B29FE68FBBFBAB5FD033EA3D1D6514548B83BCA718629453C499EA6B2C1E7005B3DAEB796F44F1FEE1B85833DFF04F2C9C9E4A34D1F8420D32B7BCB899DC424BDBAB62C960FE4A11F534F83E429230720D9C821547E3FB303B36884C285FBCDE9DEF5278A10408A6F9E3C682C4FCF8296F050E +sk = D86634ECF96CC2603761E284C0E36734CEDEC64E7FF4864699DAF37400CFE59841AFC412EC97F2929DC84A6F3C36F378EE84CE3E46CD12096F0C726DF1330754839FECF6CD5712D0EF05C08FAD2C1CBE3D4F90A207287DCE085844C86ED3DD6184D993BABBC6A5D87DE99773F52A3FE76CE2264D6A53243D976C7F793AD39E34A2971CC7ED240AA9A4D8BF959BC12456138B39A8A76223E28E3820F5C216E696E317644E8D7599C7EA9D3F1996D2B85B6C398B5E581C59E08209E53D956BD92469FBB9DF66AF0B50099CD72FC6B1E451D4B867D84A8BD3A0702C2452FF35DA3C0F051B80F68633B3030CE57B55E8CEB068E80B6C1EFE8A52665E29323CC87D942FC055FB50799BD5378BF0C2EF157BDC49975A5D334CC5E718AE4649D462291C2BCB3A3F984054FB2665E347968029AD7931BE1A60C305792BB9886D5B46E4B29FE68FBBFBAB5FD033EA3D1D6514548B83BCA718629453C499EA6B2C1E7005B3DAEB796F44F1FEE1B85833DFF04F2C9C9E4A34D1F8420D32B7BCB899DC424BDBAB62C960FE4A11F534F83E429230720D9C821547E3FB303B36884C285FBCDE9DEF5278A10408A6F9E3C682C4FCF8296F050E +ct = 1BAD4B9ED61F1069BE5892244EBFF7126496477860F990F74AFD67263AA6E0C28BFD10AD10C4DC68ADDA0668180E21203B506AAE9340FA648A55BBC98AA32F4C0D9815C9EB69812803CB1869832527C8495C3756045D4879F47E270A5687907D1461C65DF83BE7E9B2366532308C56AE2ACD6E5D932BDA099068E5548521D73CCB0D97A792E6A5B28C6E13C2C4AB8088432384991F9F1B6C78453226815B5204EE5EAFBBDE84D0A90AE19B85C818069726EE873E5D789DE7E9CC8B3D28CB9DC3BBAE8280697AE452D7D380BB2D4313C1890E91608655BDD0FFE1ACA69CE08C9011BF9E123C8A000EFD8C359F6B5DE52561C01E0EAAEC7FA66B6B7F3B26AC2CECCB35A9A694255AED7DFB63B7C7E43BD213690D24410126FF2282767A5F1E0346DC6DE1FEE06023AC12C672EB0AF8C6FC3ADBE10F9A6B3002F9241CB27975120C7E1686A212C17514E6310E48F99A7DED0FDF0A0BB0E31495E0E7E0D3BAF7C048CBE1AA03F3C4B783470083D6932724527DAA29052FBDB369AF3C23FA4C8160DE3DF62B33A21918D9CC0F8000AF3D0BB6C6CD +ss = 7D5AFA784F3C460498AAA1782428C25E4C3DC97B6F7D3125 + +count = 8 +seed = CBE5161E8DE02DDA7DE204AEB0FBB4CA81344BA8C30FE357A4664E5D2988A03B64184D7DC69F8D367550E5FEA0876D41 +pk = F25AA453B8CDE92A570B0C6E287AF984BED7ABE279F1DC437C3EBACAA7A09C94ED931D182BE098A29D99395037024B950EB6A8162ED59B3974A5EF7E1CCD32A46EB8C8D0B8A648EEEB23D81CF93EA78E85222671E17FC677EC2D33E910648A500C4472329E0717A17EFFEE478484AF217E65684406908FCEB93E008BF633708F63CCACD831CCBB410BB776601AD5762E65597FCCB12268D3D7B79EC9CA6EE4D217B6B36BD35679E0B37EAC9364605F0B100766F86B6FBB29F39D04580B232158A797786223F97C0720BDF934B163600C470A4ADD6A522C8A7CB019BA3B6D7F85BEAA9DB879993B7A83B0E49FF5127B649BB232DDB6DA1DDDB043FB0342753C5529748687DFC247E73164F9C53A418B572A52F7877B76A4DB33EE2C07E045C38B1F4F02418374AD2B930FC69D7BEA8FE23F2E2A178AB898846C3214B6F4BFF53ADD8C73A7F21EE5C84BFB178A393F7918F8B2E6D2E92795670B6A500BF42CF8B26B90211F2556A25BB40749DC9A1D723A1A7AA65BA7150A618422 +sk = 0610678FF4DC3128E1619F915DC192C220F8FAD94DA1943BDA1804DDB5AA9B1C6A47A98F8505A49BAE2AFFDE5FE75E69E828E546A6771004F25AA453B8CDE92A570B0C6E287AF984BED7ABE279F1DC437C3EBACAA7A09C94ED931D182BE098A29D99395037024B950EB6A8162ED59B3974A5EF7E1CCD32A46EB8C8D0B8A648EEEB23D81CF93EA78E85222671E17FC677EC2D33E910648A500C4472329E0717A17EFFEE478484AF217E65684406908FCEB93E008BF633708F63CCACD831CCBB410BB776601AD5762E65597FCCB12268D3D7B79EC9CA6EE4D217B6B36BD35679E0B37EAC9364605F0B100766F86B6FBB29F39D04580B232158A797786223F97C0720BDF934B163600C470A4ADD6A522C8A7CB019BA3B6D7F85BEAA9DB879993B7A83B0E49FF5127B649BB232DDB6DA1DDDB043FB0342753C5529748687DFC247E73164F9C53A418B572A52F7877B76A4DB33EE2C07E045C38B1F4F02418374AD2B930FC69D7BEA8FE23F2E2A178AB898846C3214B6F4BFF53ADD8C73A7F21EE5C84BFB178A393F7918F8B2E6D2E92795670B6A500BF42CF8B26B90211F2556A25BB40749DC9A1D723A1A7AA65BA7150A618422 +ct = B4944ED66A0ABB3791224164D2634AE2709CA5E85FFC4524009AE5CD573A36A9A5F6A87179CF63332A2B8621E5D6C96954F7CE778D5822812B99B3F2E08E3FEA74B9CFEC69C1195CF516AC83FD9AC8DE93D786E17248C8B1E8F19DE0D4E8D95D9644F36914A2C725FF35A09A975362FD87E8AD114FD40B3C7FC15D607F00FDBB332951CE21A784D523C5FD0A9B6BFE49707292CD035809B8483688C3D3B5A48F00DCCB2962032D3CC71CC9F1BC1EF908ACFF95E3CA2AE7623FF1FE2C0AF070EFC462C6933393569CF0C51B3C03CCF839B17218895D3D2884883AA66F6FD47759F140357C7D94D02CDD0686A8FE40ADCE40475587A630BAE04B50F71F9122CA51ADFAB2F271C6CC1C42F1276F8813A86161A4E2408F6DE204FEB62489F02E21F93F543BEFF07B2DE3B899627588BF362599629F7D6B0A8F23FDC62107056BA2ABE227798B53B26FAE0150C87252941136534791D4AE8C2224B0FD569D88FC9A00E41C8F0DEA3BAC2A378DBBE7B9342823F2B7317307BED7A2D8295AA616A63A2EB997F3E3A3E064164837325F2AE29C0F9519 +ss = AD7F7BACCD3229AD8F3B853754F8AFBEE4975C7865EB3980 + +count = 9 +seed = B4663A7A9883386A2AE4CBD93787E247BF26087E3826D1B8DBEB679E49C0BB286E114F0E9F42F61F63DEC42B4F974846 +pk = C2253435EF15A253726C3CDC6CCC2748FE6DA1EE0572A99BCE178C2EDE54BFDEADBAA468D54E1B85DF4113D3B01BA9CEC0406E78FB4769F5BB3B968959D12FF24E3DAC26990FB8D60C332478D3441CD07A8408A5B98BBB2A212BFE8CBBECCD80FCCD0DFFDAF25F7085D42DD19DA677C1BECBD47EB01ABCB546488D7C9C249C185F114C6EB3A90A218EC3ACF66775FD6BFE70B885594ADC3CD448497215BF99228C61205AD1CBAB1A75ED9043D792D03A8C92D4BB27828C6F39BB701207B68629D85761B31E1EB8F61350CB692441230E235B329ED5B42FCABCF4B04269C18F33E4E6AAB10FBF775ED4C8B57E14176762AD7D7C547F85A06F5616263534AB936625D5EAF46478E11CB8C67B482918E1006DB403128E138E94FF61DD3354A36E1AA66194B3437A47C3FD7B0439455F365ECEA9A45256206BBE954101AF20ED537D2FBC8CB0947610D52E8635661A60B4CD262A8F388A32FDDC123903C636FC9A58CDF343B635685D13E49734BD4DD7A6B31828FD9A7E3488DB8924 +sk = D322D56D8EF067BA1F24C92492B9C56DF3A6EF54A304ADC156047447B810CC094D400AB204CF9AE71E3AFA68B88586ECB6498C68AC0E5109C2253435EF15A253726C3CDC6CCC2748FE6DA1EE0572A99BCE178C2EDE54BFDEADBAA468D54E1B85DF4113D3B01BA9CEC0406E78FB4769F5BB3B968959D12FF24E3DAC26990FB8D60C332478D3441CD07A8408A5B98BBB2A212BFE8CBBECCD80FCCD0DFFDAF25F7085D42DD19DA677C1BECBD47EB01ABCB546488D7C9C249C185F114C6EB3A90A218EC3ACF66775FD6BFE70B885594ADC3CD448497215BF99228C61205AD1CBAB1A75ED9043D792D03A8C92D4BB27828C6F39BB701207B68629D85761B31E1EB8F61350CB692441230E235B329ED5B42FCABCF4B04269C18F33E4E6AAB10FBF775ED4C8B57E14176762AD7D7C547F85A06F5616263534AB936625D5EAF46478E11CB8C67B482918E1006DB403128E138E94FF61DD3354A36E1AA66194B3437A47C3FD7B0439455F365ECEA9A45256206BBE954101AF20ED537D2FBC8CB0947610D52E8635661A60B4CD262A8F388A32FDDC123903C636FC9A58CDF343B635685D13E49734BD4DD7A6B31828FD9A7E3488DB8924 +ct = 2A2F7F05143156B646B007D5A4C8B387D4A7B058C40BA943291FAA94616070BC87608E5611D39EEA64B9FDFCF5206548995BBD74A36EF70DC8D27D6BA4581924F163940C6DD921365F2B710DE577F9688E5D4D137B8B53C73BA07D6CA176A68F2C306F7D03B1A2DEEE16F7C294DB369889591F91F5A15A285D35FD84D63CCF80B3588AF8E676F32EB0171001B92C8F08E9FF8052796C7F3AA7BF4EB2C497AF8F67E7058CEDAC9B181B014B25DEC0AD27C30FECDBABE676BA1EB4915C3C9FFC823600FCBC42A7D6F201C67BEE9E5710C347B930EBACE47DA8F79E9C93EDD5B566DE630B400F235B4DA5223CD35CF89AAC6468ABA0D46DC2805359FB10C4266613145A0A292135D663919B86229BC3CE95662A1B957D18BB01D322C6B608BF2ACC93C684DF1FAEE7BBF6D259F8ACB7FFEF9E16806983212CF26FCB20C92A8603B572504F83666CDC08600F8027F9B821F8A2F159FCC931D974F1D32E543CAB29A68995AB9AD1481D4273329F465DC614BE638B7C5D3A5BDC8B4B1BE076C311DFC2987FAD74C04B33BCD071B54ACA0FD32B10BF +ss = BB5168A89FE38D502434B5793D857FDA3422DCCFBDD75558 + +count = 10 +seed = 980D0BA7C8F8B23D0E948A6029FF2659810EA1360064663A8994D0333C8543EE5FF5D6D5C9ACF446E61DC464F792B9D3 +pk = CA92F5A8558F4CAB6038416372906D1337A34FD4C457648923BA46AE81C1053408EE0683A47BA004E23741C1DF25CF089DFA408D00A7F39061156CBDA64B358076A74E1EA93E3826CD9380090CBC8B7481765403916FB922AFAB1AE83F2C2DEC68A64C7957C237BC76449478F00BA6ADE75DFA2F675004E82D1C0076E83D7AAB6E2E02EC1442C013BD25E08CA574A6E4B50CAD1904916289CAC2F36201739D08647BCF123F8A1D63FD80282DFAF48957A7732FACA6FADA73BC8560A13D15FCEACA788279D2C9ABEA38B09747EBE2CB419DBF07867063959FFBB767C80246AE8E4F2E70DDC028477F562F30531F4735E42E91D09B72C257B8A8EC9F06CE118C2CE07FF6C27AE93D4E542341AF03354A23964FD451C6D222BD23545B0382F9538633FEA7E0607A9096E663D810742DF9D5C6FB762A9B739DDB02861E27CBF3C6F860B5E1CC0C115620DBD0F5CD0187035E5048AD0A09808C32CC21A2200174243A580EF3865AF885B0929DF9D052EB3DE9DBDE09821D07C8DD4D02 +sk = 2F1D8A3BEBB34540324B9485FDF3D5BE3B858F544ABC3FC68D6C42E7270EE2B77B6045385F3D175984A0E260363166C73B0C70C971644303CA92F5A8558F4CAB6038416372906D1337A34FD4C457648923BA46AE81C1053408EE0683A47BA004E23741C1DF25CF089DFA408D00A7F39061156CBDA64B358076A74E1EA93E3826CD9380090CBC8B7481765403916FB922AFAB1AE83F2C2DEC68A64C7957C237BC76449478F00BA6ADE75DFA2F675004E82D1C0076E83D7AAB6E2E02EC1442C013BD25E08CA574A6E4B50CAD1904916289CAC2F36201739D08647BCF123F8A1D63FD80282DFAF48957A7732FACA6FADA73BC8560A13D15FCEACA788279D2C9ABEA38B09747EBE2CB419DBF07867063959FFBB767C80246AE8E4F2E70DDC028477F562F30531F4735E42E91D09B72C257B8A8EC9F06CE118C2CE07FF6C27AE93D4E542341AF03354A23964FD451C6D222BD23545B0382F9538633FEA7E0607A9096E663D810742DF9D5C6FB762A9B739DDB02861E27CBF3C6F860B5E1CC0C115620DBD0F5CD0187035E5048AD0A09808C32CC21A2200174243A580EF3865AF885B0929DF9D052EB3DE9DBDE09821D07C8DD4D02 +ct = FDA0BCEE27F3F18C59E58F91A3BFDFC1E5742F47BCF83C44566D612B82B9F0243489AD004242904A08B38E41C27C2B32B644F918C16418AA986152C7F3D0080CA59C4B2A4CB2C28B4813DC8FB8CEA29DD672FC6C7766012A226BD49EC289AB193FA656306F7975305014B445E84AD787DAA402FBBB9CBF55171CBBD8BA163027AAA09C0F76C2EF49CE2AC9EC0A6EC088E871162834FFCF8B0A9536312740EC83BE786AE4A834977BB1BC169393FB1D14E13239E98CD1767AF391F5E322363AEB34C9D926A578616C63797E55A0AA34B3CB7BC820888512E5B14BDD70C63E806C4D24EC3694AADC5DA2D444E9F992EFB04629DEC9E37592BEE0F4AD325AB622CEA7ABAC8E803F718B2709FB783DA81F77907496CFAEB719FC99E516AFECE3D83A9EF275500BB30CB54ACF85ECE04C8CC4FFEF90087761C73395A23F689F9BE64CB6A09C4A440A3A481490B5337A653E623329F96E6940F5E7BADCD5A8A471873CC7313C89D1F5DE2E3611C3DFB48E9E4DC2F83EDF82888FAB1239394A93AF843108522E46A11824F5463A39E68FBC3569AD41 +ss = E889EDBF6075EFCC85A5ACEADAAE48EF56528C64A974A837 + +count = 11 +seed = 6C029462CA42ED520F10A579F52687101105E0B90C6E7BFA582A4C112B579D5AD0A0ABD38F72ABCFDCAAF5893A112BDC +pk = F082E53E07B4F283BE0BC58FA3F3C514A58618519478EF0FF5631D523AFF95DC7B7AA80ABE62474782C2C6492D5C2BCB7C27C51B0EC139F9F7B4B0090F4E3B1A4FFC7E0E7521703780271D84543002C8BC3D21435F1F1214DB2CB6E272FD3727DD8D3EDAA44964F788DCB9626B1D9DC103B66EAB55A8E099A7E1A0B91D1800CA6BC21D28F54723369023B5E8B7B919281EF59F15744C9BE99C4905A267F574297369D08909A63FC280F8119E83E970B2FE6AFDAE273E7CA99127684F2FD85CEF55AB79C1F6BC5CA61F690D210B61819117AD1345B41CC3001005F808918E81C3056964F2150F828E70A03BD86B8E57554A17662AEE80411999724B16CA19C14C6EAAE89F77AA113CE9D011376E565354FDDFCB1C0DF2259EC1CA3A2A92D44737647CD9854D6D3D01A2E4D09527AA8EDFC500E5F30236DD1D48960146DF9EFD4FD208D13AC386F1F0A2FFA6900EF2A5EC81D00891DFD88DB8286C731DE4A62DA7D584FFF4968DEE7A4D46F75E1019310E3B2BD0F99DC736772702 +sk = 31BEDA3462627F601CBC56F3DDF4424E1529C04737EF0EF2812083BFA3B670E3EAF9B443702FB6DB16AC1197656BBD61A8E25ED523B8D105F082E53E07B4F283BE0BC58FA3F3C514A58618519478EF0FF5631D523AFF95DC7B7AA80ABE62474782C2C6492D5C2BCB7C27C51B0EC139F9F7B4B0090F4E3B1A4FFC7E0E7521703780271D84543002C8BC3D21435F1F1214DB2CB6E272FD3727DD8D3EDAA44964F788DCB9626B1D9DC103B66EAB55A8E099A7E1A0B91D1800CA6BC21D28F54723369023B5E8B7B919281EF59F15744C9BE99C4905A267F574297369D08909A63FC280F8119E83E970B2FE6AFDAE273E7CA99127684F2FD85CEF55AB79C1F6BC5CA61F690D210B61819117AD1345B41CC3001005F808918E81C3056964F2150F828E70A03BD86B8E57554A17662AEE80411999724B16CA19C14C6EAAE89F77AA113CE9D011376E565354FDDFCB1C0DF2259EC1CA3A2A92D44737647CD9854D6D3D01A2E4D09527AA8EDFC500E5F30236DD1D48960146DF9EFD4FD208D13AC386F1F0A2FFA6900EF2A5EC81D00891DFD88DB8286C731DE4A62DA7D584FFF4968DEE7A4D46F75E1019310E3B2BD0F99DC736772702 +ct = 8B1484EED557B154800A99F1E82A707AB16C60478C3ADBC8BB5BB0C28B161005602BDB87B8AB662C6A5C177E062E6C05FA3A9D67DEC1AB9C739FF19B501C01ED84BD10AAB12C3BEA8CB592BF1C958A8FA68B425F4801DBECA262E8BB7C6EB18E50DEC9B9755AF094AA03F4F0F78E571180FD3FFBB2CB7FDA34A07C9F842223878D4E0A381756C862E19E89C2336F50F3EF6E1913BBC2F356D8D47DE52C3516A420AF32065159D030616567E4D072E83315716A4D69F1801B42CADA963DA6CE2B3565232BEB6299824C64C32C87FFBB79EA453F9E3076AE222BFEBA21ECB5C5270A2147E4BC1E4AE55896E059CAABF943A7DB7A34B0C5AB09BA0D8922AE4E52123C8948CCE201AAA3938D70B4FAFCED7A87F9930E8960A46C38B5AB20D69CF02D0B5365773293554DC346335B36D20DCC06F4F28F4D962E64C5091AD741EAD5820F4ACB3AB72553A5E9CB05E31698F9CA67B9A120B55E31666B1B80BF170D6149646C1DABE3CE9B9B223CDDCDA94B82A1A22145F64EC05ACB8B2DEF4EF13AB37E405A1CD8E985EE56CB3123E6B3FB3B811534 +ss = 0BFB00221273D530945D57C734E626B5D744F3FE2D959B9A + +count = 12 +seed = DB00120937570D62331F4C3F19A10465231EFF46465CDEE336A0D46AA1E7493DF80F18617F9FFD0476CF7784A403EF4F +pk = 7E4A199764C8179543C0F781581F4BAB1651B53F096DE628775982B863479883214F12C2D1C975D6988C3F0DF06AFE875F1BEDE26867B184F0D8D5328DFC3A03C5390EB943361CF9A8D78C56070CC7FE167E1EB8B0FD6098778C6D9F5E7CC0B40ECDB65E38C2B4CD29FC2D5D30528422CBCF8840FE4E73FFB7732E9B0725CDDFD0AC4F449E52813E95CA1B0DC3DC102A671233F79DFC9338A946A99D7D370E8A31F4C53FF7E90CB8E6579649F82DA0463886F86C029E270A206094D717A95EF0C8D465A4CD9F75AB009C0A9AAC3D588C4C626FEF1F89220E78ED4F7AF19B81C20512344BD45E4B7B228E376A64A00716AE28A6B9D8401497D02BA71577251896B85BF5070449EC7265E7B05451B29E0567F3E59B005350D20AA08CD89C45FB7A0F0334EAC78C68C6FDB688EE7249497861BDF1D3A97D234C2FFF1DDF2693EB7E25AA235F4CC50EAECC52BC4542124DE1B7C23F1B9DD14E94C2DC6F2CC3153BD25E7F0AE5F7591C8A1426A6FB3D841A1B19715D1BDFFECD61A906 +sk = CBDFF028766D558AF4466EF14043A1A9CF765F7748C63CC08E9A30597E4B52FFA87A54B83C91D12A5E9C2CD90FCAC2C11B3A348240411A0C7E4A199764C8179543C0F781581F4BAB1651B53F096DE628775982B863479883214F12C2D1C975D6988C3F0DF06AFE875F1BEDE26867B184F0D8D5328DFC3A03C5390EB943361CF9A8D78C56070CC7FE167E1EB8B0FD6098778C6D9F5E7CC0B40ECDB65E38C2B4CD29FC2D5D30528422CBCF8840FE4E73FFB7732E9B0725CDDFD0AC4F449E52813E95CA1B0DC3DC102A671233F79DFC9338A946A99D7D370E8A31F4C53FF7E90CB8E6579649F82DA0463886F86C029E270A206094D717A95EF0C8D465A4CD9F75AB009C0A9AAC3D588C4C626FEF1F89220E78ED4F7AF19B81C20512344BD45E4B7B228E376A64A00716AE28A6B9D8401497D02BA71577251896B85BF5070449EC7265E7B05451B29E0567F3E59B005350D20AA08CD89C45FB7A0F0334EAC78C68C6FDB688EE7249497861BDF1D3A97D234C2FFF1DDF2693EB7E25AA235F4CC50EAECC52BC4542124DE1B7C23F1B9DD14E94C2DC6F2CC3153BD25E7F0AE5F7591C8A1426A6FB3D841A1B19715D1BDFFECD61A906 +ct = 78E0C28EDD5A14CBD9732A9A329AB0CD620BF2DF7394FF7E8DE4BB0F3C10F336FA4BD16255EED2A85F5FFE2A3A0190A8CADEE8CFF6CC355AC94BACC144CE0EA7A1A72698B75308A922D94CBEF3B261063FE03E7890B6519E69142CF5D88F9536DA8A914A4082D724DACEEB38521CA744E3CCA2737A1DDBE1951D8EA77A14AF040ECD1EF5DC25CD2110BEE1EE80CE953743D8151538C7150CA1B6BE445779CE03F521CC5D146CF7C77BE3ED3E438B6078FCCC230A1923CEDABBBDD04F21B29F8A83E163FF8542982C259F7E7A6A449B0EF2E71A03EA4050DDA3FAC39EFE944B43DC7BE820A2958C4E2A63974C61C3E6F8DE2F801FAE7A250D2323D00FE35A1CA08972A5854493CD79647EC3A409DF8DE4B9DB3EBBC9B16BB291895E6652F33D02D469CD322909243FFC24F7F0B2E4B55B8CA5698CD33EC0CA893109D4267A18A4001D068BB3A5CD8EDEEAEDD3E70621B947E6F38D6D5CD4DBF484302D6B0E99E81A7B6DEEE1EB2BF9E4E1F2BC670F7696CA226F017D1D368F3B39773BDF38491A9C806C09058A67C326003FC45DB8580B57CA +ss = 9701C45E2E2383F51C50E6947D7C77771C93D856199A7D80 + +count = 13 +seed = BD26C0B9A33E3B9B4C5D7EA32D5BD1FC371015BE163C86F584E49BFD5362C8D8341161CD1308115B2A03B7E5EADDD418 +pk = 46F284CFA610B61A563F13E30519DD6BF8F43D41F68BB064C8BD17B345F3406E0E40C135B409F81F769B7B13DA0DCF3B86B250E59721C874A8798B938BB635C06B1BD51A135A1C0BCEFE90E1969546BAB031B7F9E41E8631B969CAF16D06FF864D139DEF9F68317E7B4BE3E085AEC05A128C88593B4022F721D340FC65284A9F215B3550E7AA3171CD54982FD689D322DFF78D1D709AD893B3A23A217701A7F4D2F41C28465300597A5836BEC3273A198C787D6B93C777006D804560107CB8F0385718A3D55F2963D6D26D010924D22999F1699C07FCF7D833B27F791518AC6C7E8EB369BE81AC5508E44BD3AE50B5DB6DED7898600B066BA9EED6042ACE4FBC2F4511621F54D9BB7370D80CC304FCBAC19DAF1F1C2F9619DD3B51009A2D9E154780C92C656088F55198D6650E996BBE00712D4AD1481642E44E3A18A17155D104726D782E7C9F891736658210864F45B17BAAFDC903D388E8503B7C0FA3533C3831A24C80C42ED8769E0000D06FD1FB748DE31E5E3E07340C04 +sk = 4C04310BEA66305C6CA8BA6B8F61CA96257A67663AFC11768AEC87A9A79204CEE2986867A2906EB851B734B8B22B91D6749B1A5F07C44E0B46F284CFA610B61A563F13E30519DD6BF8F43D41F68BB064C8BD17B345F3406E0E40C135B409F81F769B7B13DA0DCF3B86B250E59721C874A8798B938BB635C06B1BD51A135A1C0BCEFE90E1969546BAB031B7F9E41E8631B969CAF16D06FF864D139DEF9F68317E7B4BE3E085AEC05A128C88593B4022F721D340FC65284A9F215B3550E7AA3171CD54982FD689D322DFF78D1D709AD893B3A23A217701A7F4D2F41C28465300597A5836BEC3273A198C787D6B93C777006D804560107CB8F0385718A3D55F2963D6D26D010924D22999F1699C07FCF7D833B27F791518AC6C7E8EB369BE81AC5508E44BD3AE50B5DB6DED7898600B066BA9EED6042ACE4FBC2F4511621F54D9BB7370D80CC304FCBAC19DAF1F1C2F9619DD3B51009A2D9E154780C92C656088F55198D6650E996BBE00712D4AD1481642E44E3A18A17155D104726D782E7C9F891736658210864F45B17BAAFDC903D388E8503B7C0FA3533C3831A24C80C42ED8769E0000D06FD1FB748DE31E5E3E07340C04 +ct = 1F01A47FB2A1282302175180948145041628F94B01C70BF0F6DDCA7F1148BC64D38406F7F510F61EFABAB873ACFD88214F261009B1A4690F2A62BED06EDD2D12DB1AFE2B971F3D77871A270272BD00AC6F39CC983333C84C5CCCDB14DE47503EB17A5EF17FDF70C2882D442B8D7947A1D0637ED7BB94651A07EF9AC0870EFF4BB43E5AEC6C699280CA1821C7EB8591ACAE056B6B8483B2DC99017654B79E8D1D23A7903E3B2F578DCD9725CA68A673D8D0C16E9CF374D14C2C26A6BE2AA5BD48FD4B19818870FEB4317DB65739C115FDA4E99915C8E1C198BB6F4E0FD9D80F06B08638C0BA164F64B86D5C13E2505D285354E5C1341DDC288B22BF1649D6EE07BF1A521757ADAB6EC3374A59068279D57094AD85082A53789D98E610A46B7095E61567283CF0DA206D21A53BF5649830CC23A3BD296ABA0B36513D96F19BF099B3A9D366C64C412B79015C6AF0F2F4AA34C323187E841EAF1A532635875D06A614B6175636F32D442BADF1513AE8CCDF13FB3337036C42F4250E56B8F70DFB8F9D51C5BC899DC935A7EB3C13B6FD66961AAA +ss = 87821E5176B41FF8B7516EBBF94124E2EE89911B41553898 + +count = 14 +seed = E2819EF86853BCA1B9DEE7EE1C1619988964F9A913E635AACF0D96CA6E0300D084329DABD8F149E24176D22757404260 +pk = 899C4E13C8EC0E8D6D2DAAE11FEF98BB82626B50389C198B2539EDAE55867C1DD44B43FD532C34DCA1EB6734E2BA18CD9C1233F46B3FA8E7B517CFE67FAE1D6D01510D23DBCA74D84DD9FFDF6B35944465900B336EA79AFE53F05583D649AC67722C277E9D34B6C53243FD5136E6C571E69C9F649967C1DD9DB4F6C5821F18FCECBD2CE0A9604D9FC27A19E22DDFCDD5CFF48E4A9705D5736098A1EBED32C6B1618871B50A7064E7F97A4FDA4106769A789C2BF9A593559B2C1CCA503F2473CC2FA7E62040ABF19D0288CC198113906F20564D02F850DBB695B8D0259BDE8ADE65B2AD7C541009CE6383B8BAE19628DD6DC4BEE7093471D2B916010EEABD13F42A7C9B041A976E8A48A7C3FEC40E49E4F745183D153924254F11603E571731F7877F5B4567DC46A6C178EF59856B3290FB053540C265104565EE149F7F566D508211B0F64D3B9D6AD0E2CD62BDA6DD923A05753031E7EE4F8D24B176DDEAFDDB964FAF340BFA9C1698A926ECC8999712F2660C1C764F334CFC1F +sk = 38A0D5F41D7DC1896EFD1B45B0485634CEF149828751B960A2ACF359556DF4A2ABAEB9DCEE945829BEB71185B4D6BD18B76E5668F253380A899C4E13C8EC0E8D6D2DAAE11FEF98BB82626B50389C198B2539EDAE55867C1DD44B43FD532C34DCA1EB6734E2BA18CD9C1233F46B3FA8E7B517CFE67FAE1D6D01510D23DBCA74D84DD9FFDF6B35944465900B336EA79AFE53F05583D649AC67722C277E9D34B6C53243FD5136E6C571E69C9F649967C1DD9DB4F6C5821F18FCECBD2CE0A9604D9FC27A19E22DDFCDD5CFF48E4A9705D5736098A1EBED32C6B1618871B50A7064E7F97A4FDA4106769A789C2BF9A593559B2C1CCA503F2473CC2FA7E62040ABF19D0288CC198113906F20564D02F850DBB695B8D0259BDE8ADE65B2AD7C541009CE6383B8BAE19628DD6DC4BEE7093471D2B916010EEABD13F42A7C9B041A976E8A48A7C3FEC40E49E4F745183D153924254F11603E571731F7877F5B4567DC46A6C178EF59856B3290FB053540C265104565EE149F7F566D508211B0F64D3B9D6AD0E2CD62BDA6DD923A05753031E7EE4F8D24B176DDEAFDDB964FAF340BFA9C1698A926ECC8999712F2660C1C764F334CFC1F +ct = E93B4D83DBAE38848FEDA662B665B44A4D071BE399EE432DF83A4DC62D11D473B4A544148392675354254C56A39D62B753433A519D09D48F21A843977C57227BE664ADFE662006FF5C5D42F2FFA66710AE196EAE810C4105E3BFB28A3ABB82E8CD336F30DA78C017821B9531EC328AD6AB537F039AEE48A62D5BFF8B2F18382E5D248ECE7FD5BE907832A7330FC29408B40DE3848220576A11DE5406E28DD735C9C0C98F0A636E6F5DCA77DE4F552E85B31FE021D754E8D284756E1140D896F2657146A557977753D679B8A6D56E166DABFD93678C65F374219B85ED21BE8ED10B355913A6E15217D1CFBC70CE0F4D5CF72C53AA75884FA37130000225361E4094D017DC1920A6DFB2AF4C6F27AC3A2F0508B556CA0D2613493AE7B5072B56860EC86362F9BE46CA74F7D0875E7BC060ADE85E7D2F1E100AA90C28B207D5EF8FBFC9B20DC0E05EF3E2E9B6B72A348019224F7CB93A241B96ACB0EEE3389D124CEE979CCF3D3EB3764362EDE5C501D3EE88691B5B2D07195F780CFB38A3E7AF7680E8C1ADCE22D210A15E4C682D55DE05A2E0 +ss = 40052343FF691A8F901C248C9D19CAADCEBA83B499571B10 + +count = 15 +seed = 669C4EF8A051CE201DA65FC4BC34D398EC1F806276FC5D987AD71D93BC12DC8F107B58BE6E8422A0795C88CB9A0E7488 +pk = 09E755C966DC06215F84CF51E74F1E1DFB7EEF4DBDA390CE4DE4AAD9EEA5CF40ACEC87E31D03F0D7E1AAB5B714782593DC8D2237BB2675A0C3ED59577AD4308CF6B26F49E09FBA77606EA2F5ECDA17ED1C5B04C88AF6FD5350B75F639B9C9B24BF446BCC0F903EDE4E7BC2A74FE7227B7D2F86E4DEC2CEAF1F1A4D55700F843C042A3F2AAD8E5EF5DBA29CE3CAE0065B9FCE5829C10A669C66690073CE0F28221BDA35309135C507919AD3491122A56B5AC14388A8BC466CFC0172C80A5600545A78130EE7CFCA50F253A7EFF3ADE52F38ADF2BB56D23AD6B9A86A4AA984BF2393410F205F8A4EB75197CF51E78B87E2E451E044FC6B38AA12EE450D4CA5AF80250FFC7B15D16FE26EAA08C6492C879A06304400AA7EC632050E9DAA92DD886E8F7EE1C77FA6EE10ED312E369223426C1BB91FEAE77BC6E5AF9E133550B88C7F1EA21D9A1B22B22F49DDD096BA6E87ED84DF8E1C9013A3993D2FB459A972958CA7184620C6B1E726A5356F8B8C1C5F6754F756D17BBF0F1DE411 +sk = 97B5665676E59E3538EBADAA8CD50DF1F9FDA1502D9894C6DF05318B5F655EFE36F1B678CF4B875108A18DB2FA312261CAF839F84BD9560509E755C966DC06215F84CF51E74F1E1DFB7EEF4DBDA390CE4DE4AAD9EEA5CF40ACEC87E31D03F0D7E1AAB5B714782593DC8D2237BB2675A0C3ED59577AD4308CF6B26F49E09FBA77606EA2F5ECDA17ED1C5B04C88AF6FD5350B75F639B9C9B24BF446BCC0F903EDE4E7BC2A74FE7227B7D2F86E4DEC2CEAF1F1A4D55700F843C042A3F2AAD8E5EF5DBA29CE3CAE0065B9FCE5829C10A669C66690073CE0F28221BDA35309135C507919AD3491122A56B5AC14388A8BC466CFC0172C80A5600545A78130EE7CFCA50F253A7EFF3ADE52F38ADF2BB56D23AD6B9A86A4AA984BF2393410F205F8A4EB75197CF51E78B87E2E451E044FC6B38AA12EE450D4CA5AF80250FFC7B15D16FE26EAA08C6492C879A06304400AA7EC632050E9DAA92DD886E8F7EE1C77FA6EE10ED312E369223426C1BB91FEAE77BC6E5AF9E133550B88C7F1EA21D9A1B22B22F49DDD096BA6E87ED84DF8E1C9013A3993D2FB459A972958CA7184620C6B1E726A5356F8B8C1C5F6754F756D17BBF0F1DE411 +ct = F63033C0AA277B688966223BBF280AE264F8E1918986D9557949CC936DCBEDB546C54042860ACE579543F3DD8CB7A63F785A4D46F602A1A62F73EDB9D51B07A0BA15EA074191FC880D314E02FB045EC2D626ED5EC9591FE4D3C623721BBE8AA065EA9436AE299CDB91F2284A1FCF4A0DC61E87C3DE8668CC0D022692FF350F22E80947CDB77234BAB3B79DA07B116A9EF85979BFC43DAD6944DBA64CC6699EC5F269692B9FEFEFC8B3A72B3508C0C8BDC307A69BD79C04799BFBF0A32C8E26446275CF336F15545A4C68D6B3CEC77985AD0D5A546590C2A80C5EB6EBB2594CEB0C3EF55C871486525EDB918A44BDB628D03C9CEFDCC5AB1374147D0DA5F506778229076C94B112E46D5A522204098ED58254338C1A72612249BAFB518A6543A80E2D5497AE5CA4702D07A48142C932E5C585A56AAF274D45F11D12A8EDAFE9E827FB316F148C1075C110B94B515C62A21FCF4FF463BBA0936E31BDC60264548B514EB85EF6118D3DE7567C9BC8C59E8D2F5FC491120EBDA08D08588D7147F6312BCBE81FA45A2DB67F2E4DDF0A98528CBEC4 +ss = 78720FFAE156234DD39387DE9A82199740E064F564E43329 + +count = 16 +seed = 9DEBCCFE818F6B5204DB4EA09C03EC9A19DCF1629C1527685B8A29776BB1DAAEC45F8ABF8F0ADC9A8C8BD6E2DF6D8048 +pk = 66540B0B8ECC7A013E98C10AB75F091FC0804821C984B9325C5751AF81D4FA1AE4B5967287EC424700862135609A16A9D8B3D8AF7F9F9F01E9983FB0A66A17AE297E8C5D7F3532792E338E86317E5E77EBE663CF39767F0611038B83CB8E20A7845988B3A2942EF6D550AE386F19A122EE0B7440DECD83FE153E2E85F33AC52F8BB17043936F56BDBF655D4D80A033A1B0675A776D851DD6E81AD2A3AFE7C4736DACF60AED84F5E4757FFA6DAFF062CAE256747E72DE1DE36EE90E6327F1457C265CE9B90DAB458C9093FDAEB624A7870BE5012C13C77BFB6775A2FA66075B7676457C5909CE9134A27B22B76A2608FA254C90D90CD4B632C490AE1B64BAAC2700B7D263F593B1D69F60EA72F6FF00C78EAC59C0E6F253C8F8E2E89860D2858B559F1286A05C5161DA20C5FA6B759913F436ACEBE46901BF27F90B99D76E1963D511F0C343AF99627C11EC0B209E63BC79CCA372D137D1C784138E0E998E0214242FF2A8AF51915DA75FCBC815E6E26C6271D8E11359E469482B +sk = EF99224A03A85A46EF115474EC5B5D620DA6795D6EFCCA4CDF7D92DDA83E6B2EF4CCE08C9134563063068A196D7B1A1A13623E48AE12520E66540B0B8ECC7A013E98C10AB75F091FC0804821C984B9325C5751AF81D4FA1AE4B5967287EC424700862135609A16A9D8B3D8AF7F9F9F01E9983FB0A66A17AE297E8C5D7F3532792E338E86317E5E77EBE663CF39767F0611038B83CB8E20A7845988B3A2942EF6D550AE386F19A122EE0B7440DECD83FE153E2E85F33AC52F8BB17043936F56BDBF655D4D80A033A1B0675A776D851DD6E81AD2A3AFE7C4736DACF60AED84F5E4757FFA6DAFF062CAE256747E72DE1DE36EE90E6327F1457C265CE9B90DAB458C9093FDAEB624A7870BE5012C13C77BFB6775A2FA66075B7676457C5909CE9134A27B22B76A2608FA254C90D90CD4B632C490AE1B64BAAC2700B7D263F593B1D69F60EA72F6FF00C78EAC59C0E6F253C8F8E2E89860D2858B559F1286A05C5161DA20C5FA6B759913F436ACEBE46901BF27F90B99D76E1963D511F0C343AF99627C11EC0B209E63BC79CCA372D137D1C784138E0E998E0214242FF2A8AF51915DA75FCBC815E6E26C6271D8E11359E469482B +ct = 9679725EEAF437300EEC0CF90D8052ACDF51FA28B755444DE88FDA8BBE00CB996D3AF82B6D915B3EDAA25A162A60D7AE92F8EE89BC3D23412A81E9A2EC2234074167B44273860696E5DF7296E0F9EEF2D56771BF639E4F31B2B256300E6F5A2FFA37DA78205F47942C953404DE0AD8D22FD881E2D0FF84B1CF24126159276EBA73891FBAAA48783063BDA66500F640CAC5B42E690A2D7DF9A5AEA25E9B6BCEC49CDDBD5CF8372C08E917DFF55123370E9E231E2069F4389D4CE44EF931FE8C592F76C0BB76C7041C8B94337C858FD871F8D4314CC14BEFAC903D69EE801EA3EF54115E80E1585759880C450BE7E9E6A84A36B796FDEFBE3A8038CE1E51E5BFC55ADC0788D517670396540EAF4E986DAEFBA2AA0A8E93F600C1B81084B601F459C0B94DFF767E5D0EB271457E6C6FEA9CCA1F7F934BBCAAC3DC421EA12472FD6855DF97B9DB99D1F7858323612924CCB286FDCF97E0D56E1DB3B1BBB8ACCBCFB42A20741735A89F0ADCF6E0413C79431D12F8DD94A3882528933336D49A087EF7190C1025BA49923C901617C7B601E82B7D9F +ss = 4C6DF97FE533560C98ECC1A26A597C456B4DF521F77D2306 + +count = 17 +seed = 8098AE7A92C10F707D405F7DEA02C2EFBEF44EFA132BA8AEFE81BD45E543ECEC74F10920AE48A40B0653D63532517F2A +pk = 9E85F47B655AC8BFDC11498DDA7B702D011131F858BCA91527646B69B664880994741CF637E339F6FE3298059EFC0D75822A7A8BE0804D4E48DF22D674471E9192F369A48C3DBA2361B926244E90A860E8CAE80673D15F487C66F00BD04B600518B8D40FF93007E26DACDCE31459FD0EE63243F6237AC513AD3FF50E482577452839CD397307176DE32984D92F12E4802BB1A5620B2ED84A7E2E6FACA25698C20F1F2EB2799903241E4C99E1408A57D00141D45E6736D61A968EE9F114ABF191E8D3DECBF7D8EC8330DB9A1F4EEA470E8AC09B22E14841F7E2AFD6EF2D23D2B47C77FFF5525F373A5C8F06E3F769277A88B8EFCD345E6D97D987E5063716A274361CC49D04045C2E7A0ACF3EC7028E59DD8862E7B11598C1417385CE8BF841F6EF47A70D6194D82139F015428D1C2613D8B2A7FB565B3D0974F633A41C9DFBCE89AC6263E27F3FE6CA0E23C82853B1304F0AE71E66222151A489BFE383C608543243253C025EADAC039D62AAA49C1224FFDAD9805FD481054305 +sk = B12F6FD965EA9C5B947DB80FC60C83D5E232DCA82E7263020F6AA3E88F7FA8A96067F8CDAECEEAC90C2D0B5E277E56E9C405EC9420C302029E85F47B655AC8BFDC11498DDA7B702D011131F858BCA91527646B69B664880994741CF637E339F6FE3298059EFC0D75822A7A8BE0804D4E48DF22D674471E9192F369A48C3DBA2361B926244E90A860E8CAE80673D15F487C66F00BD04B600518B8D40FF93007E26DACDCE31459FD0EE63243F6237AC513AD3FF50E482577452839CD397307176DE32984D92F12E4802BB1A5620B2ED84A7E2E6FACA25698C20F1F2EB2799903241E4C99E1408A57D00141D45E6736D61A968EE9F114ABF191E8D3DECBF7D8EC8330DB9A1F4EEA470E8AC09B22E14841F7E2AFD6EF2D23D2B47C77FFF5525F373A5C8F06E3F769277A88B8EFCD345E6D97D987E5063716A274361CC49D04045C2E7A0ACF3EC7028E59DD8862E7B11598C1417385CE8BF841F6EF47A70D6194D82139F015428D1C2613D8B2A7FB565B3D0974F633A41C9DFBCE89AC6263E27F3FE6CA0E23C82853B1304F0AE71E66222151A489BFE383C608543243253C025EADAC039D62AAA49C1224FFDAD9805FD481054305 +ct = 6E07DB8980B9B96E9680AC098CC1219926CC89488B822C013E4DBA48576FF0BBE1D34AAE5222E8F535E5851F14120B4EADC82728FD027FE11B125ACDAD7A05A8D63C18D33E6E552291EE98329FA9467120C4ED90E47C8253248C00BB132A7FA818500F2914E0E67B3AE684DF70C2B26BF23CA99A224781E706B92983A70DE5873C1DE7324FBC69631915AB9EC299B6737C3A63F8E9BBAA132BF7F1D89A788705A4CFDEB46854E68331C6104B4505D5D21ABD380E2A38523D1B1B655629917EB5F029AA73BB358D96675AE3DE8C5E8CA4301CD0C8EE08D1E0392D84575BDD0793F1D799E5CCD3F6744749DD0B6AAAD4E54B55F9B9AAB2DC2FC128ED09ED9C6A877A7CD39A09EE01C26B3E7C2FEC3E3D760758602DA0498073E53A7997AEAE68532C1165C7A030449165D5C758F6AFCADE499F0EDB664DD8E5F6D52E078D912A105883A2FF9637CDC6A43C7823F281052970761A1088C6D6631FBF2CBC6D61202C62E9A3B91A686504ED896D3984B0F2896A150682F22FD663580C454BB2C2436A1055FAB73D3F0A32DAA53F83BE4919C007B3 +ss = 28367E5CB625250393C5614DE4D4E7DDDDD84945C815B3A7 + +count = 18 +seed = D5F23808871544E9C1D6EACE2028362B48E225312F77663E9F78CAFEB512B908CD9E25875D61A16EC615F4B8FF826856 +pk = 5A71A94E0A6A3BEA30C367C682AD51E820CF9B5C4790E5B703CF9DC8AF6004B6F68970770A2303EE49AD5ECF7F48E1DF4A1F8B214B8E8274EAD984424EA5287A257D23176FCC8E0109F6ED0310EDE51DD0D4162C56FB03976BCCA82ABC94AA85A3B7DA59989D00F4CC73D84C822E3F83C1A8BE86A244E97AD8B65BC1CB37ECCF547A1B2FFAF6369A15042B106AD8F85954FCA5868AEEFCE3BBE5F1425826BEFD3F342C14C5A3071C28936C536EADC428634EBDF2B16B0CB4FE4EBFCC1A906B4860A17B5F8E333EC4DBC4E432D788C10311B261359F2F2DF74D02350C96132140E90FB67499E6C837F49FC2A87C6E3784D19301D39F4B39B8EA19E813A60F8DB75C7BD50ECC0A5F3B2F9C1C60D46D86A9E327E3C102769720A3CDA910FD9F74CAD6885B95B50D32A26CE9D55BDF84E4C34EB4211B6751AB7E9FF31B73854537DC9F4E84781CB6FC9B11D90D1F083CB1A3DF08CFC4D24114B8C0524ED60EF93CC66CFBCA043E667AF1675CC6DB6139DB4B659021177AC63784F33C +sk = 9F52AF92CA165FDC38788F2B59BA02E01C8281FF7C1E60504F3029E1BE4E1C0258C3A22FF5B50B2674CC094BA7018DA2A61569845C17D20F5A71A94E0A6A3BEA30C367C682AD51E820CF9B5C4790E5B703CF9DC8AF6004B6F68970770A2303EE49AD5ECF7F48E1DF4A1F8B214B8E8274EAD984424EA5287A257D23176FCC8E0109F6ED0310EDE51DD0D4162C56FB03976BCCA82ABC94AA85A3B7DA59989D00F4CC73D84C822E3F83C1A8BE86A244E97AD8B65BC1CB37ECCF547A1B2FFAF6369A15042B106AD8F85954FCA5868AEEFCE3BBE5F1425826BEFD3F342C14C5A3071C28936C536EADC428634EBDF2B16B0CB4FE4EBFCC1A906B4860A17B5F8E333EC4DBC4E432D788C10311B261359F2F2DF74D02350C96132140E90FB67499E6C837F49FC2A87C6E3784D19301D39F4B39B8EA19E813A60F8DB75C7BD50ECC0A5F3B2F9C1C60D46D86A9E327E3C102769720A3CDA910FD9F74CAD6885B95B50D32A26CE9D55BDF84E4C34EB4211B6751AB7E9FF31B73854537DC9F4E84781CB6FC9B11D90D1F083CB1A3DF08CFC4D24114B8C0524ED60EF93CC66CFBCA043E667AF1675CC6DB6139DB4B659021177AC63784F33C +ct = F86AE3DB047CB5C603226D712AFAEEAAF7FF161D92142AC3C37EDB2058A72D182433BD56B254BF5BF875E95C27B155AA5D7598F64BAC8ABB5F61BF1FA71539F2A985CD3715B12464D17E1D00DA5060FEA949495EE93E9C62A48760A5B25216BB2E5AB39759AE0A8A93B873ECC1CB6C332B2CFB3DAC7F311CC0ACC05F060A82A2234C32199AE9B7C8B1D9BEA4119D70B225E6342A5B03F7317BE2299023D4EB1C8A68B3AA3B6F68DCBC460484988880CFA412CB5BB22BA7DC7046366E0AD7B437B3AA2B40F534CBA2CE233E34F80207C891091D1485239910DC92C470ED15B33C41F2780A8E8D00FD6905FD617030ED756F0E96DF80193641ADF5B00990F95E049B5CD8629033F77F9D5826B7F2C84687E3A794D369062DDF00977FCE6BA97C80A9AFBE81416D12A7E5EF4ED4A7E517D5E22E3472CBB8B8C73ECE2E797F5CBF7E4EBF49BB11502BD1933C83BC9504B2E944538CC063DB3AEAD0C45DF07AB0CD4AE68A675A89B110719A5EBE1803FFA2E3CE63FE8BFE0A18682D29F0B7B8CEBC255730DE96D760DEE491A8E7B6A7848D79770A +ss = 37F56382B810B4107E0629B8F426D77EF9425CF8C532187A + +count = 19 +seed = 822CB47BE2266E182F34546924D753A5E3369011047E6950B00BC392F8FEC19EA87C26D8021D377DF86DC76C24C5F827 +pk = A3EFF37BF2DA86E5B41B10EB6321F9F5A46898E255939587358B1083102D5021407CA4B2F4F4EE2B837FA392F4DD1BF94BBA154F56968B57CC5C8FC5B6E73412A83747FD42AA5B537D7A6BA455FA56564229596424CB9F4831A42ECAA486888C7814B6DA3441792A703836767DA0DCA522C5B166468DEFA2D4485CC2FD2D5FD4990A9154F8F0C8F3D5AEDE6139DA6C9D97ABE2E8630750F127DF2AED7C76CC3AD37C9958B966C3678188CA32319340899C64A606BE8750196DA97DE6259DC556A15939ED56349695F944F756B8075A2B1AD65F6169DC33F8B8DDE8AB2C83792442378F5A5167CD69117398AD69B719E1943F3A096701FF912B585033AACFBAC194A7522D95A6EF792C0281EE8B813BD08A2D1EEB58B0FE156CDDD683CD8D582036D6779BD03F67BCC58A1EAD7CDE649DA4D9B84F864350B739583191339D5DD469F677B463E2274F36D8E270E2301541D10CF29BF10318357BE3F8C4B60697B9EA3B7896F5BB886938CF117B26CD7D1A5D69F3E2B843C68B392D +sk = 851EA90FD3854CBF28FE39FB81F68E4B14345CF0D6EEE7EC1C0EC046899A777655233E4E1B5CA44E9AFBDC67964BFD5D5E3DBB45E60D030FA3EFF37BF2DA86E5B41B10EB6321F9F5A46898E255939587358B1083102D5021407CA4B2F4F4EE2B837FA392F4DD1BF94BBA154F56968B57CC5C8FC5B6E73412A83747FD42AA5B537D7A6BA455FA56564229596424CB9F4831A42ECAA486888C7814B6DA3441792A703836767DA0DCA522C5B166468DEFA2D4485CC2FD2D5FD4990A9154F8F0C8F3D5AEDE6139DA6C9D97ABE2E8630750F127DF2AED7C76CC3AD37C9958B966C3678188CA32319340899C64A606BE8750196DA97DE6259DC556A15939ED56349695F944F756B8075A2B1AD65F6169DC33F8B8DDE8AB2C83792442378F5A5167CD69117398AD69B719E1943F3A096701FF912B585033AACFBAC194A7522D95A6EF792C0281EE8B813BD08A2D1EEB58B0FE156CDDD683CD8D582036D6779BD03F67BCC58A1EAD7CDE649DA4D9B84F864350B739583191339D5DD469F677B463E2274F36D8E270E2301541D10CF29BF10318357BE3F8C4B60697B9EA3B7896F5BB886938CF117B26CD7D1A5D69F3E2B843C68B392D +ct = CAC32EA5CB119EB0C6901B31E5800BDC1C59471CCAFD4C6E5F08D5C282B9E0DF6D2411F8602F346B2BD20945D90317F4E6135921E3022D78D4267D41D9D007A1E0B6C1C9C5C2A8153DB0248F41DD31498BFC753375CF250C1062FC3DF6825B76E0F8B938C3A4C2EAA90A5AC01A03A89C6CA2F8D5C95EF848E9A8924C0240CD96DCAF7723AFEE617315918C152E2A2BC1448EB34E589932402AB2B841AD2E9B9E5A3B2994484F59960D0D020F66E69B9985388A6CB56977E41CF906701A83AE8D8AC0CEC6C3200597D0102A1B90A8A4EFB4CFF5AC3C492E568EC216E828959DE8F703178E669042E42761D765A2CB1577ADEDB7F6A020AD8DDE56B6152B98E1E3DB908A6F3BB9EC358079E510C9EE1FCF238D78B6AD8EA82F3C70BDF44A346E27732483E56C2F3EB271B55D56422260C43A54629019296D09848431E86664C4E1E498648E85139D30E54903BD5A8458F2A67DD6EE8456077FC9D6546BB941335FA0D4B4991352E46D2CCC00DB3F1143DD70402DF2CFFF4779661E737C2305F79589850F2C8ED42E799C6A5414E5BAF590D523 +ss = 7669B8EDA6CBD1625F419F5C04D6933DDD9941441755C07D + +count = 20 +seed = 81401DB81138D6874E91B7C11D59596E4ACE543F5A3471B6FB00999221765FEC3CA057ABE20F03B2D59003375FD71FE8 +pk = 7261EAAB74955A88A029F8F26F11721634B5F141AC0B2EF106DA9D0EBC7FC54103DCC7E0E13492129B521AC87A7C68F9922C764D602CF6688FDC741BD9E11C570CDC64736A64F2570B95C31B350E3E22C543EB67E8DDBAACEED2E022BCFC6066E3846F678BEA0C976BA952859E849C5C35A54A1BFB2E2BF733391E0A643C2CFD4F6497BC54C757A341FD057C657944A635638A5AF2A53273B367634D4B969037FAE770F6EA1F47C4CF4749169ADF359CB08A3A1E93BAA6A8AA8390FF201662CBB5002F8997EDADCD10A20527DC4643852F26A167D738AF8D7AFFC2D4A28CAE19A9E470667083EDC8FBB41D071E3054DF9F7A86891EAF13F1708FB62E6F47AEAEF34950AE063850488718C288DC328106A8A9FDC111BABF747DEAC050E25726C8F1ECA17ED1E123A365231E50A057D783F209F26830A61721267110AF93341CD92D49820363B9F663F5667B5388825370B77C7F1F0C624CB341613CA0B2488FC2A8B9D381D909B825822F7BF6B44D05238342FC053B6EF2FECA05 +sk = D304C9389CC973477F169788ABCB9D511F843219D246A9B56590A2E5C7ED86CF2C5C2A898662BC9A81418720BBB632EF9CF0B845ED052D037261EAAB74955A88A029F8F26F11721634B5F141AC0B2EF106DA9D0EBC7FC54103DCC7E0E13492129B521AC87A7C68F9922C764D602CF6688FDC741BD9E11C570CDC64736A64F2570B95C31B350E3E22C543EB67E8DDBAACEED2E022BCFC6066E3846F678BEA0C976BA952859E849C5C35A54A1BFB2E2BF733391E0A643C2CFD4F6497BC54C757A341FD057C657944A635638A5AF2A53273B367634D4B969037FAE770F6EA1F47C4CF4749169ADF359CB08A3A1E93BAA6A8AA8390FF201662CBB5002F8997EDADCD10A20527DC4643852F26A167D738AF8D7AFFC2D4A28CAE19A9E470667083EDC8FBB41D071E3054DF9F7A86891EAF13F1708FB62E6F47AEAEF34950AE063850488718C288DC328106A8A9FDC111BABF747DEAC050E25726C8F1ECA17ED1E123A365231E50A057D783F209F26830A61721267110AF93341CD92D49820363B9F663F5667B5388825370B77C7F1F0C624CB341613CA0B2488FC2A8B9D381D909B825822F7BF6B44D05238342FC053B6EF2FECA05 +ct = A213D78BAF6EE1161C6946FD081545BEA4EB87F7635194BE51730AC81F84B266E32CEB74A1A9C1D02AE86546FD5A7E491F2ABD41BC173A9239BC8C7462DF219BB80E1F5116A65B60975171E8C2A6B97E359BF0A9099EDD7EADB732B4CC8095DACABF4975F3F46C65F1857D4750B66E1C4F4149BBF854EE0F9F05C0F1B21E9328039C5B619CD35B429FC498ADF560B41C699AC2B17965D20FCC1B0F9FC606BC35033D36ABF32CC907DFAFC50B81E33D6072F0C2633E3975004C3AE4F608EC17C741ACACD2841BB4CA4643E5A0E639D20DD4CF8CB5F2F050B78D589B052CF3031FB10ECC2E5F528170D5143716C8E9F2A73BEB9012C3B9978EE32441043627BB5EB40D55F833556805CE797BA3FE3825813B79ACA70BF780959FE352F9A1F0E2328F88D17B3DA27AD73045DFD188AFBF438D261635F4ED948CC9262A64ECAEECDABB7AC341E0B3F4A05997246DCC84B4C6548D91A3F28DA46AD392CE8A725A029AD3DE376B776FCA796991D5CF1545BC9CE62898C760E5F78D7A1EDF8A6D57BFC2FD586398C758F053904316B373B329BF46C6 +ss = 11EB8F2019A872C000DE74CECF48C1F1260C72756933CADC + +count = 21 +seed = 30B5DE5B73681EC08AAA03F6F2D2169525D25F4042A5E3695A20A52CA54927B85F8BB948FC21DF7DEFC3910B28674994 +pk = 1063DE3A0C40AAE9697BB166DA5E32A3CCB4337481952EA7C8894A26047EBF0D720A6CDE2878A8ABDC051F2066E91203609E1C492B7CD2E5E2943D6705C91EE19EA60AA79C2B76EE1C581ACCF1686CAE7BCE23124CCB0587ECC8C5B05278AA8728FE4E94DDC335B2169E695156A2033A9B75ED3C0532AB80883C46CFE72AC1B08C6F9669D41708846972E64F786878D0A2347F39E0F6A2119C3F2C80D2320AD6873B8228032AB1A2B00B2E0943F00A69FD023E9148E97DDB0C324FB200226BF6C440D42CE57864FD46AF8BF53FF875882F812BB74BA53AF568471483BF7B0158BAF0A75D0FCB72443451CE810131F21AE4B3CF0FF51D58287A843528C5763CF37A7CDEE1F99A396DFF768E7BE379E9C9D0F604B70115818252923577F061AB2EF4437E10D9ADE12DE44A6D3748115DE8E76A45A6D4D5DD1D4AD321055E6F117F4E99CB8DC3CD49D2DE386A21907FFC4691616F68DEFD2250FC8341E8A105059ECCCF14696B835F7DA1E8ADD5E02E33E6A2DECFDE802F99D6DB11 +sk = 89A6E3BE304A3518FB82B18CA730F0B359CD6BA90664A493B6591121E25D64010C25A18676033E1D7278AC5F2D0B43A31F3A4156AE7104051063DE3A0C40AAE9697BB166DA5E32A3CCB4337481952EA7C8894A26047EBF0D720A6CDE2878A8ABDC051F2066E91203609E1C492B7CD2E5E2943D6705C91EE19EA60AA79C2B76EE1C581ACCF1686CAE7BCE23124CCB0587ECC8C5B05278AA8728FE4E94DDC335B2169E695156A2033A9B75ED3C0532AB80883C46CFE72AC1B08C6F9669D41708846972E64F786878D0A2347F39E0F6A2119C3F2C80D2320AD6873B8228032AB1A2B00B2E0943F00A69FD023E9148E97DDB0C324FB200226BF6C440D42CE57864FD46AF8BF53FF875882F812BB74BA53AF568471483BF7B0158BAF0A75D0FCB72443451CE810131F21AE4B3CF0FF51D58287A843528C5763CF37A7CDEE1F99A396DFF768E7BE379E9C9D0F604B70115818252923577F061AB2EF4437E10D9ADE12DE44A6D3748115DE8E76A45A6D4D5DD1D4AD321055E6F117F4E99CB8DC3CD49D2DE386A21907FFC4691616F68DEFD2250FC8341E8A105059ECCCF14696B835F7DA1E8ADD5E02E33E6A2DECFDE802F99D6DB11 +ct = ED43C36EDAEAAA550871B528BDCA529CC1E6020B5FDFFC01B1C560F5DC05521F40908C3465492B4022EF5747FCBCAA88E94941766DE014F775BE8BE453A235FF1203B621B2ADFCAD1165AA074B9F8EE48F5340E7A7C8B7A03D52162A54E7CA86CA8D823EE4DC8B11F1C4818921E13E78321C097324F7BB8C0B84F2DEAB16055CD1441FEB1879A39E8B330742DA3E8C3DB19CFAEEC18EFE499878BD86A1ECC0F9CE08FD73DE79069DA27E0092F99E9692220073791F91F997C008F74430D7258D43C532E7B5A2C264E17FC20AAB97389B5CC11607BD310D992B0D5C22C7064605F1229E62512FA025023C66D3610162F713CA3A24014B13BB6DF6B32FAC8BD418AE57BA782883F50E0D185D69A8580675DCEDFD8F5DD9EE5EF36BD1119DBCC51CDAB70F62025FF1D82CACC2C3A05DF3093DCAFA9341904CC9D877072DEC93F9676F279D1D7C5F310F261B79A7F29BBF1CA799EDA656880BC65D3171318D59E6DE07EA67B2C6993101EF6DF78097C0C6D176D63F9701A774F2F4004C13EDF46CE829F5AD4B7C08BF1AC99DDC826FE240CE7C43 +ss = 2802B84BABFC1973FF4D9D2ED0CB2B190E017A010F21092D + +count = 22 +seed = E335DF8FC0D890588C3E305AC92C7160FF199E07C85760A828933750E3FED8C83B0DBE802234481ECF890A32D7A2884F +pk = 322060E201FBE14AB5E71E898CD8424825E2C00638F2FA97074C2A709207319EAB1C571F01E2363A279E2E309D54401C73D3C3F983A6C128A95AFF66F2362839EDF382615D6CA303F47BDE4916B304205903EBBAC1777CEA70E04371FCC37D69AE7D42306C1198F8EDA2CFADE624DCB24F15945E1FC4FA7EC5C862CE7A2248FE5F009ACC4A799CA1027691F2A10B137B03B955F9EE2571CD8D2369B73BD00874304D90872A392FFE0A2679FC1E377500FFBD304FCEA72194CF35523B0DD59F0CD61AEBDC4D6B19D5FEF211290F869A1E2D1D4B342C554C9B90C23E57E4DBA3C99CBA3CF6F2058A621DD2AECFBBD7921753E19929245DB3DECA12751EEB4AF875521440441DB94017E10A54E13C520BA7D90F53A44F36D06182CFABD0FF50BA28F6A34E1A51DFF06001CA9CDA552393A87DFCFB1A9987D2136ACA0096298CB60A672A2F2F6D7326BBDE9BEA62917B432D4C022E4A081B5A9D429AEF49ADC5D6CC2BDCFE08A385E590F9912F02CB56E73E8A2046B9536B02B0B92B +sk = D569B935CE015C85F792F8F7FB0D83C4F53B492959361DD476EAE84D11C4528382828F7A689A0D5CFF87B8CA0BBA97FEACB39B935A87880B322060E201FBE14AB5E71E898CD8424825E2C00638F2FA97074C2A709207319EAB1C571F01E2363A279E2E309D54401C73D3C3F983A6C128A95AFF66F2362839EDF382615D6CA303F47BDE4916B304205903EBBAC1777CEA70E04371FCC37D69AE7D42306C1198F8EDA2CFADE624DCB24F15945E1FC4FA7EC5C862CE7A2248FE5F009ACC4A799CA1027691F2A10B137B03B955F9EE2571CD8D2369B73BD00874304D90872A392FFE0A2679FC1E377500FFBD304FCEA72194CF35523B0DD59F0CD61AEBDC4D6B19D5FEF211290F869A1E2D1D4B342C554C9B90C23E57E4DBA3C99CBA3CF6F2058A621DD2AECFBBD7921753E19929245DB3DECA12751EEB4AF875521440441DB94017E10A54E13C520BA7D90F53A44F36D06182CFABD0FF50BA28F6A34E1A51DFF06001CA9CDA552393A87DFCFB1A9987D2136ACA0096298CB60A672A2F2F6D7326BBDE9BEA62917B432D4C022E4A081B5A9D429AEF49ADC5D6CC2BDCFE08A385E590F9912F02CB56E73E8A2046B9536B02B0B92B +ct = 504804BCEE2367489287F34680A5FF306E2A10CE9F9E5A378541EE15D59B9E1850813D026B5BA8B4987CB777C5E881849E55B433CB99DA4FEFB846465F7910D9D90A1CD88C91466A9A587F12450427028A62E0FF10B0201172F0A051735DA6828EBEC7F320DA15FCA42CAFBC5F407307EBB025E6FE7F291834A01AD1670730603E33E3039EC4501A8E2462F95CC2D2020CA5A4DE9DD8B52715F2321E76D938A029B8988B5847D0809C47B73A0C70622FC75B7AC8E1754EF1A48C5DC9389A8395BC6B4FFFF3BA14450E3D240D831FB8C7F4F078FB518A345D50042CBE8904BCDDE2E3B9C8C05C18C09440628F54A6763156ADEF10D8AF1F6EEED7951773BCD85A9A13AC0E7D24AC99E5D911091F9BA73159C42E2FB08FC23C68F2FAF3F78301BAC2A888523C07038F2D6BFC6454FD926F78047982EA929353937F190307DB27A9BDDA708CD24463999E0A8B268F9E51F4D5E9EF2B29952923CA68376C4F6B006928F5B6F38C044F057AF45CC7BFA9D5EBDDF3D85DFD4EA449DC3ACF9F27778F8F2CC859C61409DBA2E18C1D9C26B05B2FF0D6 +ss = FF9EB3E0434A52E2883FC31009E1F6D10C7E505E324F9B78 + +count = 23 +seed = FBEA1BC2C379F4F8FDCB0DE260D31CDB064C9EA9B1D6DFBE91B3692ADD1D34DEC9C9FFAE7BF5E72ED2743BA3F9F2E43D +pk = 8404DF0E1454442A5E0D1E76D532DE241549B89549824CCF457386EA44ED293B99702C55079A11A7FCDFB7A14FE4754639A57B0D957DE4C7025A9AE21B723A5F67A2BB4278584D6ABA3F1935827DDB80A6A8EBFD7B3F0C7F3DC4C1D3EA781AAC3622C62F242AC431A4D0F1BE84945D2E39E5ADA2D3524F1D18DC8FF2EC2BE38BFA612E67CB34C449B048A7D0ACDEA0AE259195EF7C8BEF6F19ED10D10DECB4E63618F1A6F55BE9612D49B8487052462F99DE604499D650821141A63C3C4F08C464B454EA8BBE598303F46570D6BD2513C273B65CDEC458C391BCD4D745448F196740607C58B7DA68C486748D46364A284F7C2E2442E2FDE485E57E13A466F512F2500C17714C3DD4096756EF272D556C358F7E52D6C1F010B20E777B6FCCAF94D9A077E60DBABAEFB53E8847693EC1E7D42970C2DE6C07223E981A8ACE5DCCDAF0D41BAD3FD63E2AD674F92ECA472B8AE33C758D4239CDA7D68E66F6EEBD2584266BC23BC38E687073971A24F6976E0EFBEBE69DB4F1B956EF31 +sk = 5CBB141C2763425C274F7404FE530D9116E08C33F9F200A2FC9EBBE336DC464489861DB8253606971BD0A9008A433ED17752D040237815028404DF0E1454442A5E0D1E76D532DE241549B89549824CCF457386EA44ED293B99702C55079A11A7FCDFB7A14FE4754639A57B0D957DE4C7025A9AE21B723A5F67A2BB4278584D6ABA3F1935827DDB80A6A8EBFD7B3F0C7F3DC4C1D3EA781AAC3622C62F242AC431A4D0F1BE84945D2E39E5ADA2D3524F1D18DC8FF2EC2BE38BFA612E67CB34C449B048A7D0ACDEA0AE259195EF7C8BEF6F19ED10D10DECB4E63618F1A6F55BE9612D49B8487052462F99DE604499D650821141A63C3C4F08C464B454EA8BBE598303F46570D6BD2513C273B65CDEC458C391BCD4D745448F196740607C58B7DA68C486748D46364A284F7C2E2442E2FDE485E57E13A466F512F2500C17714C3DD4096756EF272D556C358F7E52D6C1F010B20E777B6FCCAF94D9A077E60DBABAEFB53E8847693EC1E7D42970C2DE6C07223E981A8ACE5DCCDAF0D41BAD3FD63E2AD674F92ECA472B8AE33C758D4239CDA7D68E66F6EEBD2584266BC23BC38E687073971A24F6976E0EFBEBE69DB4F1B956EF31 +ct = 92D49914330E0763C7974214C56F421EB4FD986468991002176F83E198EFF0D5CF1974B05B2557F0D571779B49BF10EA3654DBC4D69A161C76C740747E221915B36F005061D3391B48533B3CE381953CA626BD53ABB52B690524870182C48043EF9D918447D07800ACCD0D18D8B662431A4771E1C125857AE8ED5FF3522F686C42AC4598E3FC2AE39EA996899A166FB9524CB34503058C030EB5E2A5AFAABC5B1702BE52F699A62288D2ABD57A065AF779DB676E013C5373E392DB0610778CDAD725D37B330F6AA5508A762CFCC53629795A93C1B61F592B792650AB0C9B7DC48061292937392F78E37B49AE9B05C0A2E8CF535F08EA5890CE58593CB6D215EBD4D5B7D3411436B77EC2D0E41070B3037E95AC3E1B8A05D095948AE821FA08EE14545CDCC5E14C6BB462BCFC959A4CD35755E4B48826E46C0C033EFA5046AADBA600D6797AA8343D7DD9C68E162A878037F10F1CC975CF891BD209AEE75C4402C1CD54236CBAC600D6EF46E6150A2A36F2A8E918E20BC597DC1C93C99D8CCDC299A659D90C8084DC08FFD8726A0C14806DB2 +ss = 25356B80E1208646C29DBA5EF1348D3265E8FF9E767C4465 + +count = 24 +seed = 7E87FB886BC3C7C9FC12569F465D2ECD12532E76CC27C65644C8D3DD603B0CB2D036C5974E675058F271D5C82AD7A813 +pk = 2E3BE7D5145FE035B276D38F787E7FFBC0A5FF06668DFE061D7ADD6669889976ED33CF943E1080AB1CE733FD2D52B71486A3292FF0AB898F79FBF78414B414140EF8C5E473C60183663AA2BBDC2B2AB41BA74ACE4C0BC4F9C65E3355A214BD6CC66F8B2B225D6209786F1962120366669581DC0DB4455DE42333D2807C253278BF2EA4BDECD951787B0C5EDC38ADB07FB75C713876DD11A21DF595C47909A9A7518AECD77BA8B7D78EEC1ADC6D0D2B11CD4D71828D8BA70E3BAFD50F2E78837F1E90FFE09BEA05EE65013FA1154D568222553E9C6F4DB6A1E1F182E58DDD9699B6DB7D0182713DF2A05B543E49FF7726FBB4D5879EE9845B920BB60A3FF23D4AABFBC5BCAFCA0AF53825CE6EBD142C345F84C4CF4F4D59BABE0149E652F59A9844428446DDBBBBC6567777DD1E20A626D272797287FD730FACCF101AEAE1A08B093BFEC545F32FF0943EE0A914A23145784710CA004C827D27287242B9B48752C374D1F0D7AEA1C83DE5221F65BE4DF21C5901A8954A097A9E05 +sk = 293ABB6D1C207927945417CF84883EF010823E11B487ED55FF8563038AAD865A817CAB9CE98846BA75BE9363718ECF5FEA538AEA90B2A5082E3BE7D5145FE035B276D38F787E7FFBC0A5FF06668DFE061D7ADD6669889976ED33CF943E1080AB1CE733FD2D52B71486A3292FF0AB898F79FBF78414B414140EF8C5E473C60183663AA2BBDC2B2AB41BA74ACE4C0BC4F9C65E3355A214BD6CC66F8B2B225D6209786F1962120366669581DC0DB4455DE42333D2807C253278BF2EA4BDECD951787B0C5EDC38ADB07FB75C713876DD11A21DF595C47909A9A7518AECD77BA8B7D78EEC1ADC6D0D2B11CD4D71828D8BA70E3BAFD50F2E78837F1E90FFE09BEA05EE65013FA1154D568222553E9C6F4DB6A1E1F182E58DDD9699B6DB7D0182713DF2A05B543E49FF7726FBB4D5879EE9845B920BB60A3FF23D4AABFBC5BCAFCA0AF53825CE6EBD142C345F84C4CF4F4D59BABE0149E652F59A9844428446DDBBBBC6567777DD1E20A626D272797287FD730FACCF101AEAE1A08B093BFEC545F32FF0943EE0A914A23145784710CA004C827D27287242B9B48752C374D1F0D7AEA1C83DE5221F65BE4DF21C5901A8954A097A9E05 +ct = 692C1F81A0F96716FDE5270FB9CC64E40750E604522C2BBEB0D8E994F545C05984A3A3F9B9547F5892CE5A54370B417E4B1646C667561C43684A9C60BB693878C2777DE07A31C4C8959DF4F479C8EA8AF1FB60AA6942AA599123DFCEA7C896F6C19CE6618E7475B698F204C11FE0EB709A2D40FF2CBFFC9BFAEFECEDDA2ADC67D1E301DDF2F587EC16576F0394ABEC4E60E1D6CC3B68EC900FB6649E318EFABA3B659BEF40E6DF6AFDA50EBDB381B1B709BBC2D813D85FC6A1CE0BC62997DB3A84EDDE23CC8006357247A1FE3C70469F16719EBB9E176CD3CCDB69727FA3F80C0CC1E9D777083C00C28932F58CD4A739EA3C19533B9EC9683AB127108152C883BC12764EBEF9E49454022F52673CCC7939B4D9464F3E158DE0C8BBDF2645C416E6E617FEF6E1460415F6E7DC45616AA23DD0948C7F08E38D76093382345EEFD49A0C56427A0655B68E9E3A0F64FE675B553A46B20F833494272A28B81263A6484CE2622FDDC1B1747E6E41A177F68B2210D8E3880F24FC5EEA2770CF3E3787D56337122E301682713DF1A8F8CF0FDE53B15F +ss = 8D38A9FB575D15AEF5725AE38E75203DB4AFAF6D43171914 + +count = 25 +seed = AD1424E804F306C7FF513DA4C1E8D445AFCA7BC942FAC5C0B335733AAF70693712ECBDE26EA726EE0F9FD9D52A83B1A4 +pk = DE96C16B07415B67553420B347DD8782E5FB834CE71744D68A423A4775F14D2D2A9373D049097352C9979E8F49D235D12EDD7608C4A2A7B52CC610698D653A8D573A111D9F42EA748C718E5DC82D5F429F12FCFACF6DDF3D95E38BB9429FD23285155492BEB51C18406A50EE0861940844A1C834CB6D579D23E7FF9546141EB6C8AC8BF6338976B1DEE0A89B1871D00060984639984E74DB5FD5D35BAD61B80192B0F1D044435E1470811B7BE30AC0D9A8BFC7C6E14B65AE67636443400AA5A0C764D65D3617E35556AE46D8D08BA8CCFB83A8905500C5259B9A665C5842435089EE8296B36E21FF50AC47A3F47F4D7BF16AEC0AEDF382F23D65F3362F3C06CB6880FF5BF953941EB076EABDC6F135619DBFCB3C705AC9C742BA67AB5E98C0ED21F8AAC3DFE8136AD67B82C27A07259288381C8AC39F31F998331F9E4226F102E5F4614A1C9CA78FB5B16F47F7EF3FABE5E50A01EDEDEF687B1263514FDA8A8BB6EA150150B1C8E7F6F0045F450454F5FA26A58ABF8757FD5C20 +sk = 74D87C7556F2671F2D666854A4D6E073E69F35421E6E1A42E1FB7456AC0AA1B97068F452CBA64EBDC138BCF5D36B0A0FADA2A3B374141E09DE96C16B07415B67553420B347DD8782E5FB834CE71744D68A423A4775F14D2D2A9373D049097352C9979E8F49D235D12EDD7608C4A2A7B52CC610698D653A8D573A111D9F42EA748C718E5DC82D5F429F12FCFACF6DDF3D95E38BB9429FD23285155492BEB51C18406A50EE0861940844A1C834CB6D579D23E7FF9546141EB6C8AC8BF6338976B1DEE0A89B1871D00060984639984E74DB5FD5D35BAD61B80192B0F1D044435E1470811B7BE30AC0D9A8BFC7C6E14B65AE67636443400AA5A0C764D65D3617E35556AE46D8D08BA8CCFB83A8905500C5259B9A665C5842435089EE8296B36E21FF50AC47A3F47F4D7BF16AEC0AEDF382F23D65F3362F3C06CB6880FF5BF953941EB076EABDC6F135619DBFCB3C705AC9C742BA67AB5E98C0ED21F8AAC3DFE8136AD67B82C27A07259288381C8AC39F31F998331F9E4226F102E5F4614A1C9CA78FB5B16F47F7EF3FABE5E50A01EDEDEF687B1263514FDA8A8BB6EA150150B1C8E7F6F0045F450454F5FA26A58ABF8757FD5C20 +ct = CFAF97FB2DEB322300BDCC3A1CDD9E84BAA5CECCDBF2740EB215B8C58FA704A141ADC1BD7C28C577159CDEAC50FDAE1CAB47154652F42B44C92A93ECC3F122A186D8F6DFF24B92D3D4FD71CBFF589DD6C23153E2702A79C2301C2A0FCFF4E3DD098F8E9C9278D4CE05F986950A71A5D2CFF7C2D0B2B44D77E114765BA6134C00243C2C6489F6299F3C2589C8566E4BD65C0D8698BAD8C5BD9036BC14CBAE8C2A8DCB6A54786554EE77D8239528F80ADB3858044FCC464A9136BFAE511B5482E53264747E7C8B8F312293C315C950961DB73C8546F9A5F03483B778B8078B6FF53D8F6C7BEAC95E6359CB9E5DFF32A312AEB9D1EC877C5E2DC16D42101CA98CCB2B97923D5518A029F0C7A77D02762CFF7D8A4B45952362D537556A01BA534BF9FF0F5D9F5ED65017B61D2EB562F5041AAA411C06577FC7417058077C53B308A1DA2D37DA5F3B59312A522AC1E754324B9CFF4BD1EF14B6F17FC2FC7D996F2D49E0EEDC4188AEA7C98FF4EDD9C3C1216115B5D7850426370CAD2D5B0B9EE861A1EB1F27191D22A24D814AEE81868604EB7C4C +ss = 46A4994AFBC3A5F11BBB0B1764169F37C03C65C265331C70 + +count = 26 +seed = 7C33CA0E987226C8524DD56C811FA4D1CCF9995B1E4E4DD5B1481974E88CFABFBF6787775C2611CEFB27ED4403EA9B46 +pk = F9702CABFAC90350ACC8B15011903B929AEBB4506E007515B5A7C39772E10419907665DFCCA3B13001C5834AE0A14815617585EC5F457FC6AF32D0A0C517225E7E8ADE36C9A07A5463D7FBA59C45EEDE33C1DD3BF79BA273D8A0DC63897D0CDDC1049AB9AF817E26105D0C33734BEC2321B041D3E6E1539B640453C55B2F6A011594580AC1B9B5A5931A3BA3D227BC5E15591EF55BCBC79DCC88F160A189A32BBC174A69092935DFDF561C191765E4632DC9E0C4D6BE21E75F0E2474299E13750330B9200E5C560285D907F4A8CC277D4B93FCD3208F14C108B48224A4C8485659BB9BC7CA9CE5A546E2739CF38679604CD3C0043E8F3EE3C9827034D1E703F0C18673095D598372A716121F8FB1D6EB0C2C114288C143DB327CA2D94125F995EFBE3A513F49CB36A293F951276503D90550FDD7EDB34150232027C3A240BE190C18C8F1C0139294A0FF9CA530401AA388D1F09604E3D0546DB69D56DDC77E2B173B0262149924B2BD3160D0D9763E320996A41EE7DAF5562F0D +sk = 013BAB0212D04ECD54B478DAF72748003A25E2CB060BA6CC9DA0C5DA5F195B80FBB99C2E8B06926074F3F604B3F6195B5A5B9737876BBA02F9702CABFAC90350ACC8B15011903B929AEBB4506E007515B5A7C39772E10419907665DFCCA3B13001C5834AE0A14815617585EC5F457FC6AF32D0A0C517225E7E8ADE36C9A07A5463D7FBA59C45EEDE33C1DD3BF79BA273D8A0DC63897D0CDDC1049AB9AF817E26105D0C33734BEC2321B041D3E6E1539B640453C55B2F6A011594580AC1B9B5A5931A3BA3D227BC5E15591EF55BCBC79DCC88F160A189A32BBC174A69092935DFDF561C191765E4632DC9E0C4D6BE21E75F0E2474299E13750330B9200E5C560285D907F4A8CC277D4B93FCD3208F14C108B48224A4C8485659BB9BC7CA9CE5A546E2739CF38679604CD3C0043E8F3EE3C9827034D1E703F0C18673095D598372A716121F8FB1D6EB0C2C114288C143DB327CA2D94125F995EFBE3A513F49CB36A293F951276503D90550FDD7EDB34150232027C3A240BE190C18C8F1C0139294A0FF9CA530401AA388D1F09604E3D0546DB69D56DDC77E2B173B0262149924B2BD3160D0D9763E320996A41EE7DAF5562F0D +ct = 12BBBDC2344D6F29BF4CEA447A5B28283573EF13BC0975AA96EDE6D9478CEB702D9C3346A205639ED29848EE51F50E858A54E2CDE6BC867BF4F807391E1415B465162FB1157FE2E828700084892B3D04EE7764B2575AB7D517FB7A319BEBCE90C672A1574E2808E918C9CC44D6DE05525A07D522918B65BF320218326409962B263AB2E2B479707FE73D079D59AC976227961BEA2AE293FC4FE01016495B2E1ECA1DF8E7C6FB4B15831EDDCFD6CB58CF16FEA6ABB172B1B622E0603F0506053881C4F12616D8386C2054460EFF4DB31A2B0FF1EBB4BEF106F80E7B3FDBEB95503C891107876381D01D3EF5B9A46D2F658986C59F94CDD73031D55115384E13562A03236A54DC6F8A73313AFBF37F222E0047BB44DA44C6F9FBFBC50DBB44C7251C4903CCE7F7DD8CB43FBF563A8EA19438DA37AD58BABCDFAA6023725374691A47F43D082EA53A20924D795122CC263E1AD5FA4AC08DD17F632D831B0B38231136C7CA1699A1A34D3C0C62DEABCBEF4ED6BD1D500ECCFAF9760FB68A756BC77426482D0D3BB435522E5BF7049603A936AB6C +ss = 50070F02BE770A0C58C395E7B59ABDCD9C94DFF0CA296C83 + +count = 27 +seed = 54770EA1252EA2857D6635151194F5F520ADEA8A41E409FF498D40C271359858FE2B084D5B96BEE087B8E8F4DD4E00C5 +pk = 291A8F3BBD365D420B0586C15B829203BF35D8CC7FE21FB231ED26391A11236AA7200288B2835D6B83B19CA656426E8353FB9470AEE8DF7D9B5518FFE1D228301087B700B2AA519AF8ED7B1CBC48CD5605EE85CF83E9FB4407D2B70863A893AE632D6FCB8F6DA4C44E2D230E28083AC1416033FDEED2ADF38BAC29FAE42FE71AA37417A8B49EE4F51FB2AFB3A90B98259220F7E682D968BA3DC8EA3988FCFF870F470DF78326801EAA7252692543EDF788791CEAAF5ACAEEE99BF5E62964AF577E0E8CB19C6F2D19A2E12E5457CE52CE4915C30DBBE90555B2FD1A681B54B9519B90F01917BA59CBA4007BFED3BEAD35442E2122FD39CA4DD6A72034E0DAACDE29273D3FBAF00EC5D3F52A3CAF2B142A1C3CE780CC618401757C39D860E71FD92A020C2B72722822C111B11AA223F3A9C405D29F9EF3F030F10D254132C8DB81BEE40D49EE4B88E47F35AAD2B08BF6EAD2CB28085BE2559DA4BBEFF753C851ACA10037321EFA13D5B9CE5BB5D1F622CFA8ED271D597CA812251B +sk = CCB073C4B90BE0AD746E26FB093B60C70110BD1DCBCDDB5671600A8982C350DF524CDE514431DED7AEC23576530894BCBF0EC0BFEF0BB60F291A8F3BBD365D420B0586C15B829203BF35D8CC7FE21FB231ED26391A11236AA7200288B2835D6B83B19CA656426E8353FB9470AEE8DF7D9B5518FFE1D228301087B700B2AA519AF8ED7B1CBC48CD5605EE85CF83E9FB4407D2B70863A893AE632D6FCB8F6DA4C44E2D230E28083AC1416033FDEED2ADF38BAC29FAE42FE71AA37417A8B49EE4F51FB2AFB3A90B98259220F7E682D968BA3DC8EA3988FCFF870F470DF78326801EAA7252692543EDF788791CEAAF5ACAEEE99BF5E62964AF577E0E8CB19C6F2D19A2E12E5457CE52CE4915C30DBBE90555B2FD1A681B54B9519B90F01917BA59CBA4007BFED3BEAD35442E2122FD39CA4DD6A72034E0DAACDE29273D3FBAF00EC5D3F52A3CAF2B142A1C3CE780CC618401757C39D860E71FD92A020C2B72722822C111B11AA223F3A9C405D29F9EF3F030F10D254132C8DB81BEE40D49EE4B88E47F35AAD2B08BF6EAD2CB28085BE2559DA4BBEFF753C851ACA10037321EFA13D5B9CE5BB5D1F622CFA8ED271D597CA812251B +ct = F316D53D5B725385AB4BCC544E4780DF98170CBF13F151D7B4D982E20C28B40F31EFD10834354629DB586AD71EDB938E68615A2A3D28B07C8D2F73F3ADD204321619231D23806BC72CCD19F26FEA8B8F12A2C9B267B433E319E920C372C5F6D572BB417E6B95342C261E0575563FFAB24B30B198DEDCCA56A0F81C1A47066317B79EE4D70BB1C8898619B53B7494A79FC0E80ECE5BFB234CC7D52DCCBA3509B2F873494FB054161F0231A0B289BB8FE68F26EC033C9AE702F842A7DE21A9F005DA980F2AD2CBAA8D10168E4FA94418896FE1EC4CD30BE8190A2314173C59F27CD833233BB158C83344714D27DBC18C52AD79AC4D33D17B7A0C4E110FE1391D0CC10901BACBEFB749E092DBBE33A1359F120E6AB56E511A1EF013B270297908DCF82B9A7623C05E77CD63994346C6FC4D893D15C7F1930A045C9E1676405B978704C0EC9D08162D6DD760B9149B64D8A7629797DDAF678FF7A5A3118D34B4F06751965942D1ABEA1361854EFB7D2CF645A23756C65C5A45839C106D752819C90710915E7315F890BF5E7652928197CAC3CC6D +ss = 63579BEB1B9E77A63D12C42ACCC45CB12113BBD158A98B62 + +count = 28 +seed = CD6CFE94E9C0A1CC4FFDCD2D7876504BE5F50F1D1CA5CF93482943465B268276056F2781F4DE805C138976CA72621387 +pk = 87D7F0EA9A83C8FF9E507D0E66268AB7E20A5BCC9630DDEEC511C0F321EF86CD5EC5C9EF8769CAE18DBC600A54873A1059378736DC9D6F55ED8C692DD1EC30F897C5E9F9C6E84BE8BEA02773A99395591E237372E8FF1D484B56DF2D54EA10ED20B32FE64D97857862E46CB3825D0DBDB031319E4871120D7202DF9F7B2B045ABA4907111D39F8DDDF1D35F078DF3970515C753C169F5B4F1AEB7CF154F307C68DBF095BA4D6DE4F5D932C14841DF41A8E4627612E6B2CCD7E7D8EFD1417D69B18422AC7420B316B143E6BBAF5B52AE02935DB5C77652F3380394307CC5DC60CC712B3690BBF6ADC5028ADF63194402C8DE5AF46DC27593723D7E622F8ED04804DFCE3A800EFC35C40066FCE4A66AE2A60CDAB5F11E340A2358666B5F6B2D09592E9D653D12562DAD1C661B23E96A5EE068C5687D8690CFF9A7235B46A5D4B60E112755E3F9FBB92A46EDCA6D7029F578C0053D7FE34A3E6663FD5437A500E47B3E0F6F854878E5AB499D63FA567D350EDC5314E7BE3BF86FC31 +sk = 2E889F44E28901E9AC7CA6B2FFFCB124C8979401B17064D70E145E44AAE52CFC609E6F47FD7A6F6AF877190FF52256D0AC5B05B89C3F440F87D7F0EA9A83C8FF9E507D0E66268AB7E20A5BCC9630DDEEC511C0F321EF86CD5EC5C9EF8769CAE18DBC600A54873A1059378736DC9D6F55ED8C692DD1EC30F897C5E9F9C6E84BE8BEA02773A99395591E237372E8FF1D484B56DF2D54EA10ED20B32FE64D97857862E46CB3825D0DBDB031319E4871120D7202DF9F7B2B045ABA4907111D39F8DDDF1D35F078DF3970515C753C169F5B4F1AEB7CF154F307C68DBF095BA4D6DE4F5D932C14841DF41A8E4627612E6B2CCD7E7D8EFD1417D69B18422AC7420B316B143E6BBAF5B52AE02935DB5C77652F3380394307CC5DC60CC712B3690BBF6ADC5028ADF63194402C8DE5AF46DC27593723D7E622F8ED04804DFCE3A800EFC35C40066FCE4A66AE2A60CDAB5F11E340A2358666B5F6B2D09592E9D653D12562DAD1C661B23E96A5EE068C5687D8690CFF9A7235B46A5D4B60E112755E3F9FBB92A46EDCA6D7029F578C0053D7FE34A3E6663FD5437A500E47B3E0F6F854878E5AB499D63FA567D350EDC5314E7BE3BF86FC31 +ct = 649B502E3525F5A7A44B02D87A99FD680722545777CE89282937591E7835A1902FB75442EADAF7CA52DFC81B07EECC318DA0FD3C2636030F748C290E303C1FE89C244C87DD2F294C7B82D97336B667D0AFB27B94115E1F44903D990FB7DAFDBDBB208241C9A2481D1ACCA37F37CE9F3087E0E5F793A044D614E2E168160814A704145515BAACDA5BDB385A5A36CEF07B76744053E37AC6BB827CAB5E36978E825DA0CEF2ED020A07DCC5097206AB6538DF9D56165B6A1E66A6A52229156C4498F35DC464DDA5ADB9619E88D639B9737875DBF584B6592F039E8C4CA7289D670896ADC39A19741E034E09D07056BE256EE94CA7BCFC0F51FDDB59F605A68DA0BFBBB937694E5ACD9C89B2161FF482279591D422117F22329A8827E6B2818C16DA21AE8765E3C8BA9F9682F5A334D754ECCC57028DF69FBAA6957724CB284C7218FB36CD2B9EC96D6F8E1243C333DBE6EC25C8988949FC37EBADE57075A5E3475185471EB7F9C2E2B55783A8C9A0290F463F67193C0B2EA1B5BF1333899363E0EAD49AD6DA5FCBFA970BB89EAA1E41A822CD8D +ss = 7AE5663B12E00FB60985F50DC46F2CC949E917EB3C313C8A + +count = 29 +seed = 265EB2DE7099E4BD5614E5DE7F0C2A05C78EF3E8E2DD4AE4CB70F3E5E59C8D1D88248303F07DE0C5508652DA66B47222 +pk = 861D2AD089C83BDF336CF64288A2E593DEA7BBD292DF209B461638382A2BC335813B7CB02206E01785F68AA8C8D7945DA2055A630D0D759820519272B05131CCB861D640B03B598B2C8557907AF1C7CB26A281ADC9E4DCA55237E1076A59B9E0DD0949C71BD94FC5F1B19D747A56C0A7E710222873C966B60829A0C67B25E0D529BF6A7AC9CD0E4C7DA74C8B98DB5C31606FA77223E0A0D3B8908C1A339D38E84050C8BE7F5846F69F6B7FEFC64AFACEF5ACBEDE2E02E2DC665E511B3DB6D33AC1113A59C5C39A742E4F8695E5D6F20D1C8402AECBF007E4CB5EDEDB86929973A71CC797B429AF8D4E39FEB5E1902DD15BFCA0150B517C200411BA2CC164C02E38C9910687390C1DCD20B41EEC081C893F3F4080A5FF0CF2A5AEB3EBEC7F59B92838CA2D80A4A22F806B4A470B5EA2E6B8443AD8E1908BD6CDEF0FB796B83D0DA6994906547C254F6A8F02399A591A44EB027BF6FEE85BC2C27CD0F3A193E42F5C00E5DECABBBEEE59818A3BE83C93005D5AD7EDEF5A859A4C24 +sk = 174AAA36410566DC15A5E62874218D7ABDDE0B2C0F30D87750A7A2354F7E5CEFA6F4A4E9A1C411EB9364506E9E1204A8ACB3CB77FBD2C40D861D2AD089C83BDF336CF64288A2E593DEA7BBD292DF209B461638382A2BC335813B7CB02206E01785F68AA8C8D7945DA2055A630D0D759820519272B05131CCB861D640B03B598B2C8557907AF1C7CB26A281ADC9E4DCA55237E1076A59B9E0DD0949C71BD94FC5F1B19D747A56C0A7E710222873C966B60829A0C67B25E0D529BF6A7AC9CD0E4C7DA74C8B98DB5C31606FA77223E0A0D3B8908C1A339D38E84050C8BE7F5846F69F6B7FEFC64AFACEF5ACBEDE2E02E2DC665E511B3DB6D33AC1113A59C5C39A742E4F8695E5D6F20D1C8402AECBF007E4CB5EDEDB86929973A71CC797B429AF8D4E39FEB5E1902DD15BFCA0150B517C200411BA2CC164C02E38C9910687390C1DCD20B41EEC081C893F3F4080A5FF0CF2A5AEB3EBEC7F59B92838CA2D80A4A22F806B4A470B5EA2E6B8443AD8E1908BD6CDEF0FB796B83D0DA6994906547C254F6A8F02399A591A44EB027BF6FEE85BC2C27CD0F3A193E42F5C00E5DECABBBEEE59818A3BE83C93005D5AD7EDEF5A859A4C24 +ct = EA0A417DC1A13A15DB5FCA1AA40ADEE75F0EBC983F335707DB45B74E1A57BE06EEC132A7DBA217339408B004FF8899F1AAE064C49E8959D3CE6F054E426508413F62A78F38BBAED74F943805D38BBB57896741DFEC86E29D56C4E3E60F5FC5E293601B86E8FE2D5F54ECE703242B3EAECF627FDE6C03CAC65F7A3C03272637F510F8B4D92731F4149C5837072E7E1FD7169DA5DAFDDDAC4B2C248EED3F24FB004C763D655FE46DE11A7E6FBBD6D26B4956D06CBF4D72127C19A662D21413B46FC9AFF4A06FA5F6FC9C1A072DB9A98BEB805B82B7667A4AEB0D84B1FC4D6D8C42B4DE4AA60DAC7D19E66007BED6D9D444853A25CCDD11BF8222FD903E9B9B08E70BB3425A499313725148A70C8D3A959122F77077891384F152AE433ACCAC91D029F19C706EC0ED16148315466666C9776AA0B5651D566671575028A784A6FC5C38A8A1FCB7B986373A861493E6EA1D8F5C24CFE0399BC3695CFF1026CED8A1F2017F2DB363ABA2E08AF8402807656E49F92986660F8C615FBC3957B35C2EAF0E885D28BBF6FF52B97F460A649B2544A357C0 +ss = 7BDFDADCAD41A5B6822F31918D6D7AE2E281C88856EFFFE2 + +count = 30 +seed = 806BBD111F27C2668318387BD0830F65EC21A51AF01985EF48D03D64E1958FF7EE5133A4EBF6DBF36329BCAAF65F40EA +pk = E16A0B7CECAC2BA42CF6720F6D7F7AAEEFABAE71DC5E0B4866918398FAB084577A61833594F9A952EA9D0B9CA27DDE1962108582AEDCADA542ACA37A5C951F25FAFF743093881BAED9968ED76AA66502D9ACA9C4E8EE77C9458B6547A1CA8FDC59E6DC068D78214A1EF59552CA13AE9E6B3369884F32CB8008D884332F276DFC45B4C8EA45DD06F7C6E2B06A2FAEC19E3EF043626CF41B8185E69D43B99BB5619B879DF0E1A3F7DB449036DEE49A2C1C8DBB2F93135DE579F317D95913DD00A87AF2E7A7C46F1CAD9AAA7F2E2666CD4368DD4DE0EC54972D52E0AA0BDB8C7B7B3594C94E905573172B6E40E130D3849B3D75812D3DF5E1123A3E91151FBB65662AE61832E1711CEF1238841D9F6CC7BF022BA84E7036A7DFDF338A401DC2E20185A750DA16A07A1E1E2B3347DE84C5451252D3295AB31908FD072D726771A91F9336E8D022460A48F2BC4FFB958E3DF76726019FA20C1264BCB732792BC67C4E7CA2A54BB58927AD01F81B188CEC2932C5917496AD63AA414A26 +sk = 351FE4313E2DA7FAC83D509F3103CAF7B4C64A4D458FEFDFF072D9B5A99F9C7A0A011E4DC10F6B600D611F40BBA75071E7BEE61D23FD5E0AE16A0B7CECAC2BA42CF6720F6D7F7AAEEFABAE71DC5E0B4866918398FAB084577A61833594F9A952EA9D0B9CA27DDE1962108582AEDCADA542ACA37A5C951F25FAFF743093881BAED9968ED76AA66502D9ACA9C4E8EE77C9458B6547A1CA8FDC59E6DC068D78214A1EF59552CA13AE9E6B3369884F32CB8008D884332F276DFC45B4C8EA45DD06F7C6E2B06A2FAEC19E3EF043626CF41B8185E69D43B99BB5619B879DF0E1A3F7DB449036DEE49A2C1C8DBB2F93135DE579F317D95913DD00A87AF2E7A7C46F1CAD9AAA7F2E2666CD4368DD4DE0EC54972D52E0AA0BDB8C7B7B3594C94E905573172B6E40E130D3849B3D75812D3DF5E1123A3E91151FBB65662AE61832E1711CEF1238841D9F6CC7BF022BA84E7036A7DFDF338A401DC2E20185A750DA16A07A1E1E2B3347DE84C5451252D3295AB31908FD072D726771A91F9336E8D022460A48F2BC4FFB958E3DF76726019FA20C1264BCB732792BC67C4E7CA2A54BB58927AD01F81B188CEC2932C5917496AD63AA414A26 +ct = 89DAB815D870E4A03A93561A62E7C2CB92F2AE47A42AD328B0CB890F8F51D08A5A290315021C9D367D9771DEFBCE703AB4EEC3E95E847AFB04F9AD133D402D8072140038F34078147DF5557BD16397E99041A5ED93AB508FEF0CB8F0076C36511308D646ED14B13BA18D86B1584D31AB58E02D82CB51B2CB700ABD12B6132C8A32133A3735336632F93F819DC6B453FB26C2A7AC2D608A55ED4F66F12CEFAC56D4C40AE5D61AC127DB5306B8E77A194FB134509A1EA7E389A095D73C226493B79FE2F8B36DD1A676FC5B96CF032F02DCA55351F98C94C7E57B180806C1734FE9E86C5F8B87B58C31A53D397D1CD0EBF38E6A19654FE1D9E7AC3AEC38C569136F756D93907885E4437F0BD7C0B19DD1F8E47154517F1E6946357945AFF596DCBE00C8A54AEE7C525D09812505C7B292DA6485D3E96C260F4236083657B96D427E38B42C5646536FF28615C4147B66CC7E93FC25203B49B489CF7D4C049AE67E559576B1BF625C104659029A300821A94C54669964CDEACFAD13396193B257EC8B9A3E373BEF7C553DCABF1DB7F479A04FB587 +ss = 2070A68D724543C3916FC37A02561C82556DB7A8EE97BEBE + +count = 31 +seed = AD540A9CE816D6FB1661E5483C44F6FDD00C9E7BD1A8CEDA4B4C4D3697D4F78ED0A56954996CCB7DA96ECB8F5CB15809 +pk = 8F6E9B55DEF00BFB64F921DB6A0B0FD0DD406608EED52BA4E2520CB3AA12F3F2A03BF3455289E5E15FD5758D8DF76A9E1881E50C61A96607355551B613CA144E02AFC251B865AC4E32E372157B0FA8872BEA3A8C0CD1664E219FC448A9C7D6E45EBFAA419F6723848B8A2DC1EEFC2586C5DF963BD1E332775BC0D857CE2B226E46C8ADA7882F25F560459B14853A5504C768249329ED0A02A639E0A1A762897A4EEA39C3CFC2378BACD7FD4C4AC1C145E4D0445FDA73CD219C052E021D5FDA380E9EB420511E4D296DAF8D2B4C64E737A511E2DB24658EFB2BE85AC088E6B5D40836E4532927DADB505C787C00C857A8B4A9DAE85D0313AFC9DEE0289C2C08B8B9BBD661F8DB4ECD84047ED64A9900E093C7B7BD277905D21965DD46061F9B2D4C4E4A7BFA97C65677251E2FCD2E09EF52A88B4E09DF7DA9CE1D0DC9D13AFF2A0514CA20629F7540D0B90ECF59D9EAFDFAC5931C54C49F0DC994F21B030E823266081F770775D5F7825B0D4FCEDBC8899FAD0A9A9B07E218C336 +sk = 9BC5315580207C6C16DCF3A30C48DAF278DE12E8C27DF6735A4D0A8A41C4F666854E9B13673071CEB2FD61DEF9A850C211E7C50071B1DD0D8F6E9B55DEF00BFB64F921DB6A0B0FD0DD406608EED52BA4E2520CB3AA12F3F2A03BF3455289E5E15FD5758D8DF76A9E1881E50C61A96607355551B613CA144E02AFC251B865AC4E32E372157B0FA8872BEA3A8C0CD1664E219FC448A9C7D6E45EBFAA419F6723848B8A2DC1EEFC2586C5DF963BD1E332775BC0D857CE2B226E46C8ADA7882F25F560459B14853A5504C768249329ED0A02A639E0A1A762897A4EEA39C3CFC2378BACD7FD4C4AC1C145E4D0445FDA73CD219C052E021D5FDA380E9EB420511E4D296DAF8D2B4C64E737A511E2DB24658EFB2BE85AC088E6B5D40836E4532927DADB505C787C00C857A8B4A9DAE85D0313AFC9DEE0289C2C08B8B9BBD661F8DB4ECD84047ED64A9900E093C7B7BD277905D21965DD46061F9B2D4C4E4A7BFA97C65677251E2FCD2E09EF52A88B4E09DF7DA9CE1D0DC9D13AFF2A0514CA20629F7540D0B90ECF59D9EAFDFAC5931C54C49F0DC994F21B030E823266081F770775D5F7825B0D4FCEDBC8899FAD0A9A9B07E218C336 +ct = 9E8B1ADE8007D87B97B409729962367225B30C769E463AFC2F7FA4654520DC2F02AA438413B4BD33612995C12A6C0CBF2AB3ECC19008CCC2A2612A13EC911B1AAA03A5F511F0A2BBC8C106311CDE81F12D0783F43F2F233EE53668358FE9C38F4A64205284E6C70F6DA3D848A1F38C3CA52F06831A4A8117621EF7283C1D26556CE894A64820F7F36B741DA252DAD3AB5DDCE62BEDE4695F9676834BFD4C6EED4514CB464C3610E5AD525B763A262478021BDB312D3F5B3283D09D30161E28EE5F66DA495692EBBDFF6A09EC7C351BF4338E63332701A40B8EE17C2724E04DDDAE50F3C1747CB73A5544F130D3244A8047D8105C3DF0627B836C7F35B8698B51452467C6C1C104FE9882EB1142533D42DCEDC7D80DD8976CCBABE3FC7D679C50208259A09937512223A6864924AAA77EBCADFDC62C1A32A97EBF012B369834DB79AB2AFE6F37CE73478BDDA693391B811876033B44348D831B791F7877F63B098381BD7B7E209E92C298F724D5FEBAC1AB3EC2FA009E49AEF027FEE29B39EBA284A0B82D1B692BF5BA88FA74F550B37C116F +ss = 0AF322CD0E4C18F9886C22C619E933858A45DBB3FF192835 + +count = 32 +seed = 288A5F2684D862A86D2790AFDDDDBAC6FDA934EE7D2E6DA1508BB550838609E8107312B28E00A6C01706374CCD3AEFA7 +pk = 2851227F9B4806BB389A3C606D5C1A2C1BD3251600BF972FB3BC1979A0FD898D33A5D6360414901BC9E8B4B78F2C8F0F68ACAFA3DF1C0D4C575D03EFA9C13942E99DE673B5B4A7D7F3A157C7AF219CCBAC995BC3CF0EA739B9F7776C20770FDA835D8F24EF47570842BFF3192493BDD6E32B1CF129FAE8578D04A9AB1B0FD0F03D95BD237FEDED3AB9AC3438C2891F601E8210E9803F2E643EB9CC267493192763BD10D672D5EC43D2EA7C57D525DAA352999D9104505C187BDA23310F3FAEDFC5DA02BB99390510A9BFDCF47785E2B8A2A6B9D9DD985823529B7EF69CF8E7C1A152AA57FA6A6D5B95F56EC883A9E169B16C525F7EE9994F46191D323463B5A89E32CE08F3286D1EA67377F5C83914AFEA3B9B3A7F07729706E4ACC4FD37D5576AE80EE62F82C8E3034DC3C7366BA0231E5B727231E0B408CDCF3835DE2287A027BE6E7FCECAD9A290D548868DAEFEF01D83F2B0373EC80DD1ABEACF8225EE671649F28FE3457984717B4E601FA803F4EF9164CDBDFE73232939 +sk = D8B907B34D152FF8603B73051F772DAA71EB902C47B7E2F036B817736CBC5F7B1DD6EEF5FE6332FB1A598F3871E5470D440FD2EA631DA20A2851227F9B4806BB389A3C606D5C1A2C1BD3251600BF972FB3BC1979A0FD898D33A5D6360414901BC9E8B4B78F2C8F0F68ACAFA3DF1C0D4C575D03EFA9C13942E99DE673B5B4A7D7F3A157C7AF219CCBAC995BC3CF0EA739B9F7776C20770FDA835D8F24EF47570842BFF3192493BDD6E32B1CF129FAE8578D04A9AB1B0FD0F03D95BD237FEDED3AB9AC3438C2891F601E8210E9803F2E643EB9CC267493192763BD10D672D5EC43D2EA7C57D525DAA352999D9104505C187BDA23310F3FAEDFC5DA02BB99390510A9BFDCF47785E2B8A2A6B9D9DD985823529B7EF69CF8E7C1A152AA57FA6A6D5B95F56EC883A9E169B16C525F7EE9994F46191D323463B5A89E32CE08F3286D1EA67377F5C83914AFEA3B9B3A7F07729706E4ACC4FD37D5576AE80EE62F82C8E3034DC3C7366BA0231E5B727231E0B408CDCF3835DE2287A027BE6E7FCECAD9A290D548868DAEFEF01D83F2B0373EC80DD1ABEACF8225EE671649F28FE3457984717B4E601FA803F4EF9164CDBDFE73232939 +ct = 41B3A6C85D9213AB240BAB88919E5B1A7CF2D712A12437753BFC63DDA5CEAE74D1E541E14520E7002B692D602E0A1F9A9B9DC1C2A67E709B3964613DC8CD1F228B590107B3DDEBCCEF13CB112BB3A47AC23517A238E6EADCC248C814108DCE5E5BA87C0929055678905512F84E0558B6DAC96159884104BC722CD00C8C0D2134DBEF1C66E239E03370D8FB61BEE020B148B7FF4D0F0EF4F3905A1DBF73490B187DE5119084E50BF1E8646850DD6ED3EAE5A45901BB9981BEDE5892C0336FCFC0F7737857447B88DF99BA7409361F9881301D7550036A2CEF54A6E1A45FB5B69915FD61861141A7D654CDC7792DC1875B5B7E3A43318C9A76A843332E00597166CA459DF137104F831EC5AEC36CB7F74B0B7FFAC43E39DA944D98772FF26E64D30F352D73C22E5ACD3195CE346340803BBF77041E7C46BCCCF1BE049013BD0DCF60AC808D54A2BD3FC01400B56C3272D1B5208E6F79FEC64B3F8F57E45FDD2A7814A1AFF12CC5DC5552EA94DE4990C9C543EC406A6FF9C5C68C1FC7FF7D0D9248EE5F888B66D325E58C4F61FFC25806F160F1 +ss = 7DE608427494E125EEEFD9835047F49D8375C7A5CAE1BF2C + +count = 33 +seed = 4635DC5BB92EF98CDB6220DF0DD717C7F8158375EAA2B78FC3F0B58E9C9653E92684CAD3461D9158A481DA3D14694C44 +pk = 1F69DB2F480DD270802C0AE5F305E7B1CEE2EA9F5B498A5AE0833FFF215EA12FC8C156461AFA33F2CB8867C0DCB552AEE51E94C076648AF66DEEFA7047B721021D5176708ED7601A7F0196C13DBD2024B5002592D407A91719F01C8CB209382855F9416436E67C685ADB5414B43BDE786953AC23B9D47DC8A5E3DEA780380F6C1FE089BAEA89D15399DD496D18A7564E89751BD3D0C6485E3961496D39F6A0652D20DC65DFAA51198AA6D2CF384C63233F7F92A328FF5014CA1E2698384F79A523CA43F689488D7D5A5B1E0BD9FDC66215AF26924611A550AC6991EFCB67A2ED9C6731BB0D6A89DE32FB91E8667B1380A09A3F1A21BA0EFC710D1E30F20C695ADE281701B5439C455E87D46F74F8A5BA77A9CE8CC2FD452A3B198C5AD422D1179EE7ABD1527E4267857F3CF73C28BD3653AE5484EA4AF427D8570B263A72F5EA59D9FA25C2359EB6101A9A72356F2748589DAB1BD3D576D288C214CBB485048F17586D9B85D473FB0CC5C4C2269861CF1745749D5E606FAC2D0D +sk = 684A29E4E5480A5F2533E1526B5FAC8CDF5927F3D85087C775D12195EC32A8686D0600E45D4A7F54219B0D7A3826D193A51B9156ECF2ED061F69DB2F480DD270802C0AE5F305E7B1CEE2EA9F5B498A5AE0833FFF215EA12FC8C156461AFA33F2CB8867C0DCB552AEE51E94C076648AF66DEEFA7047B721021D5176708ED7601A7F0196C13DBD2024B5002592D407A91719F01C8CB209382855F9416436E67C685ADB5414B43BDE786953AC23B9D47DC8A5E3DEA780380F6C1FE089BAEA89D15399DD496D18A7564E89751BD3D0C6485E3961496D39F6A0652D20DC65DFAA51198AA6D2CF384C63233F7F92A328FF5014CA1E2698384F79A523CA43F689488D7D5A5B1E0BD9FDC66215AF26924611A550AC6991EFCB67A2ED9C6731BB0D6A89DE32FB91E8667B1380A09A3F1A21BA0EFC710D1E30F20C695ADE281701B5439C455E87D46F74F8A5BA77A9CE8CC2FD452A3B198C5AD422D1179EE7ABD1527E4267857F3CF73C28BD3653AE5484EA4AF427D8570B263A72F5EA59D9FA25C2359EB6101A9A72356F2748589DAB1BD3D576D288C214CBB485048F17586D9B85D473FB0CC5C4C2269861CF1745749D5E606FAC2D0D +ct = 9C6E885CB748B175A54CD54E393EA735103286F88F1D4A28BE4FA3EA45FD26ECA4C8E7A26827DCE44A4DEBC865B9EE19475666359A3748946B4AF29CA35B0EFA242C13A9C7838AFEB3EA213DC27A0BD6537E0B75980D391A5C656B231B184D27AEC59AF09EC91431416B00A45DDFA4A521B0D6CC17FB7CC7F61C250AA521360107F17954DAFB5F39E10D55398447B22C95339CAEB0AF27A42C240E318E5D69A8157DE8DFA9AEBB8843D7C6AF0DB9015622063575B4A611223C1DE7AE27A059893267BF156F944EEA98E822802613DB1E8B02585025FE89BEEEBB5A51AFF0F046FF2DD81FA5FDF8D69BF182979A376F5766B6CA865843007826665D2980C14C886176917D736EF9AF4B8723B2E3FBFF274CB768FFE1B2E8CE2FC59FD603F33494CBD96807D17D24B3B89E971FCB6B7E5A882CC72915CC954428811494A80BCCA283BB57CB8F60367497390CB5B475D77FBAAC936796A1366B05B4AA98CCD265D935215817DA556F0DD4A46CB95B6705095F89249200F949039B19FA407CC7702B209D880898E20B20D4BDD9AC2FD680D27F4C +ss = FA133C56508F068C3BA387BD3E0664A420D5F8F427901B6C + +count = 34 +seed = 5DA2C51B4ACF488C8BDED5E985CC4702E4A7BCB248B5AC18AABA529F7F9CBF30EFA776E99F76D5C1686E94F50FB57DAE +pk = 2E425A6B1D61FB128904AA452B44460784FBF88F246390CACC101BACB0164F80C73ED13E0AF8F15B5F48BDC6E3C8793E6DD123C8E4E25D0A24A3BBBF8D5137F44E0F6432A3240840FC054E89D75FCD15CA0F4609E5152E91534212843FB683D9AB45BA31FF8D743015B02A397EE65187CA0AABD1AE0BBF628DD9B4375D0E281E58BBA0FE64AF04E68BAE1A2A3CA62B2A37F67E92B441860A3DE06E2BF730F3FF44858A7A0A71ACBC98B1E4D70A193FF41CDDEB64AF006A75EEB3B39E2E85E8ED755DFDCB6C68947BE80320FAD94B67A923D0FFF54ED80FAE190DEE68C263B6C96EACBF35F6CFC9A7141D80ECBA9B318006077D2F1D46B18553D39A2D4296AEDDA1BA814CFD42E7878F06A7BD7E364C3F3E81E1EDF0025B82F9A9FA14A99170B42416C5EADEA9CA53A31123BE4BE12D75FDBEA23682A1440FBA062AB490DC4B4E47A3A60AC7CD3894AFDA1272DDF95D582AD095EE08014B8033BBE86C847585245FEF2B0C0E224542B030E630E9A7B05DB27843B1BDA53837ED2B +sk = D76B3573F596EB286AB5231FEEC7499686B13021BE36CB12248C0A21EA0BB6D6F56F12300E8584D8E9A34E0E6F52227281151AE4C305FB0F2E425A6B1D61FB128904AA452B44460784FBF88F246390CACC101BACB0164F80C73ED13E0AF8F15B5F48BDC6E3C8793E6DD123C8E4E25D0A24A3BBBF8D5137F44E0F6432A3240840FC054E89D75FCD15CA0F4609E5152E91534212843FB683D9AB45BA31FF8D743015B02A397EE65187CA0AABD1AE0BBF628DD9B4375D0E281E58BBA0FE64AF04E68BAE1A2A3CA62B2A37F67E92B441860A3DE06E2BF730F3FF44858A7A0A71ACBC98B1E4D70A193FF41CDDEB64AF006A75EEB3B39E2E85E8ED755DFDCB6C68947BE80320FAD94B67A923D0FFF54ED80FAE190DEE68C263B6C96EACBF35F6CFC9A7141D80ECBA9B318006077D2F1D46B18553D39A2D4296AEDDA1BA814CFD42E7878F06A7BD7E364C3F3E81E1EDF0025B82F9A9FA14A99170B42416C5EADEA9CA53A31123BE4BE12D75FDBEA23682A1440FBA062AB490DC4B4E47A3A60AC7CD3894AFDA1272DDF95D582AD095EE08014B8033BBE86C847585245FEF2B0C0E224542B030E630E9A7B05DB27843B1BDA53837ED2B +ct = D5435AA3764B0FF9EF46AB4E53FD14BBDD8B273E7B28C5F51985B51B60458A9CB067CEF38B716A2FEDB26B4987D215BB2CD8491073D8FE5A0C0CAFC842EA2A79E6E32BB4314526E13CD603636B2093A8758F86458E612C5779DED1520096E090F7F1D1C8C215B3C753884FE64BD751F32E9E20F24D713C900F88889A870C22D0B0819BF0EA626C23885278A0B12B0A2B87626137BFB9AE32951FE669161CC024BF8D31D4542E099E2F2977EBC6A81A3B7318A958D65D858E82A526640E95AA7D7216BFBEB37676118D949F86B7B8AA7748A405F6D449D57A5D450EFB8E75954BCF5C535CE026818F2EE8E354A8EF2F4750C107791977EA008BE99B1984499BD8AD62D4C73CDC23C8A4BAE5EA9940F020148812DD49E3056FA92772D0E429CEB146D06A2A5DD98A4A9AA461DB52B008180FE6901E24226241CB431310B09E1EC82C7C6F6EE6F8B41CAB44743E9772E591B900D3120D8DF2553A48736AED97D9253A907BA5A2B4CA70FBCE27CE352367A924381C5AC120B2605A3874BF587C79A130AC76D27ECC438A92EE97F347BD3A4F49D2 +ss = 03F6FF9E4AEE904E7060DBE69BFC53DF8A76F7FE8C07A482 + +count = 35 +seed = 4D2239E84B052109A78DBAB6D80C51A86D38248105970476B74A0B78B9CFAB6283E30D5A406FAE1C7F54F8BAE1110EE4 +pk = C616F9854080080493E779CFDF9ECBE5F776C39EAB7F5B31BF025E57D71A525BA0878CD7A1CED694A38659EA95F73A3E77FB7061E13B2B5AE755A2232A971CFBBB2378D477ECD3385C4577C61093273BD93655F6D461290613AD7C6DA4421FB3386FAA5FAAE6644EF4811DDEDA30ABAA933F5BB0F42009F489259E0D7C3E80D0B443595B34F4DD2773703C260092DA7CDEBB045585E151E1A42CF2029F850F82911D9827F78C33778F79C8441523599629547B06C093AF90FADF501F2BA0C36F5A334CDCF7E6E4670944C98ADC52606105B7203D15A82ECE04F0559F604E34335493FF24C6A9BDC14734A35B0C6B2BF8082C19FF196ECFBA975C47258EB6BD96925B6958438ABDF5095C901C7C5143732BC83F4A215289E627A4AF5029FAFDEC294B82A62A047E4D7BEDF182E1282228262DB95EA6B077F6538D21FBDFCAA1998906DD64B4ABAAEE576AD7D9FD08F8D8B275CA2A9FBFC1DDF0717D02D97A520EA51CFFC50075DFF2AD7A8CDFCDAC1A1BDEA89990BD9DECBD7521 +sk = B87439FDE81C9E39EEBE7CF741C685785532C1DD23E8EF861646460817A0FCE5836BDFE124A7448E7ADF7B8ECC2652AC6D280E986682DF01C616F9854080080493E779CFDF9ECBE5F776C39EAB7F5B31BF025E57D71A525BA0878CD7A1CED694A38659EA95F73A3E77FB7061E13B2B5AE755A2232A971CFBBB2378D477ECD3385C4577C61093273BD93655F6D461290613AD7C6DA4421FB3386FAA5FAAE6644EF4811DDEDA30ABAA933F5BB0F42009F489259E0D7C3E80D0B443595B34F4DD2773703C260092DA7CDEBB045585E151E1A42CF2029F850F82911D9827F78C33778F79C8441523599629547B06C093AF90FADF501F2BA0C36F5A334CDCF7E6E4670944C98ADC52606105B7203D15A82ECE04F0559F604E34335493FF24C6A9BDC14734A35B0C6B2BF8082C19FF196ECFBA975C47258EB6BD96925B6958438ABDF5095C901C7C5143732BC83F4A215289E627A4AF5029FAFDEC294B82A62A047E4D7BEDF182E1282228262DB95EA6B077F6538D21FBDFCAA1998906DD64B4ABAAEE576AD7D9FD08F8D8B275CA2A9FBFC1DDF0717D02D97A520EA51CFFC50075DFF2AD7A8CDFCDAC1A1BDEA89990BD9DECBD7521 +ct = BBF92F9F87591B6857ABDCDA8A24CEA7EB9E8FD233463C150DF9D68E0F462EC18C64155FE8B6FAEAE7612D2C0BE461FA467B5B5B5F4858CF2764727594470223FD646FBFB7CB2B61D4577751490D7A66BB43B6AA7310FC179B0DBD799522612AD8985555CC1B662144F6EBFD3B4947FC27A34593911B3627375F2004CC08091DF45F542A5756919E6CB6150DD894EE11DE6778894274BC28A949D96F04D4C5157555DCE4601DF233439E7EA1254BFB414D2D74815DB0A3B4781699100F53732AA9F2F57792A9482A7063F4B97EA373779443535B7A7F8273F391D6DCB1BDBA159285C8F94295D660E1E150C1A86EEC52754843CFB0645FB03A93263E59A7D59307130ED94868161C61E7D1584A21859C1EF78F3FE90300667899C4D03CDF45F87B52B7ECD76B437CBF0FAA7425F38038E6C3321925BEE46AE6130CCB78FEBCD6B36085EF5F9B3A9F83F65DF4433865D746F5CD40A5C195237BCEA3F5D6216A17B9D387828EAA48135A1FBD58987020129B979152AD6D194EA53362B2BC59AE9C1DC9FAC1534BAF8BA47A923E20E7F39A3F6B +ss = 0E6998CA7260CDE93D7CE60CA8CBD1AB6076EC79DBC94377 + +count = 36 +seed = EE762F5C9021C36446706A88EF16312F4A12C725CD7AFFF1484337C91EDA8E89F7007F3705747D29907B3FB7500E5074 +pk = 7D6DB450BB97FA0557B94795596DD6A65F956239F0A4924D2E869CBFD8E30FED394CF80B473FF51395F0ACE8CE4A50AF6335152413562B499DA9AB75E07203B8A6F178943400C8CA01FF7CCC00183FB917C44ADBF09335BF9011E824EC1C687A91608076DB1710DBC0C98AC8443C447A2ACA28367FD11A840E4891A4D834F911F58E44971768B77198A18629B66BF83B8187B81E429A07946CEBF46ECA19BCDC2841E65A8E09D7C66C2087F8BB9F49A9CF2BDC06ABB3960D188F1C4104C6F69DB354198827EA60A6BA11C366A1A83868F06892B306AF2C7A9BBFA3EDDA6277BA761E877258BA29EA013A0E90A404E1F8C17FB41C1B18F55F18BCD02CC523C3CC7DAAABB55545BF618434C3E09138388E3C583800C52C5A1261AD7E1140C5FD812E8BB9A7DAF4D75EB0A2E773C73BFB2C1C4DB4E95070BAFD37C23BC37AD988913D2744C195976B0B52B7DCAA1BB31ABF59565876BA98DACE8763375362CA10E42568D68212413AD4F78682D24E3925C13CE6EBF23D2BA8EFF335 +sk = 056661B38038DA4FDD7426F32A81576C73ED84843B30516879238A80DCFD7C992D84B2DFFA67493E669243D4FA38C46B090BDF86BC5484017D6DB450BB97FA0557B94795596DD6A65F956239F0A4924D2E869CBFD8E30FED394CF80B473FF51395F0ACE8CE4A50AF6335152413562B499DA9AB75E07203B8A6F178943400C8CA01FF7CCC00183FB917C44ADBF09335BF9011E824EC1C687A91608076DB1710DBC0C98AC8443C447A2ACA28367FD11A840E4891A4D834F911F58E44971768B77198A18629B66BF83B8187B81E429A07946CEBF46ECA19BCDC2841E65A8E09D7C66C2087F8BB9F49A9CF2BDC06ABB3960D188F1C4104C6F69DB354198827EA60A6BA11C366A1A83868F06892B306AF2C7A9BBFA3EDDA6277BA761E877258BA29EA013A0E90A404E1F8C17FB41C1B18F55F18BCD02CC523C3CC7DAAABB55545BF618434C3E09138388E3C583800C52C5A1261AD7E1140C5FD812E8BB9A7DAF4D75EB0A2E773C73BFB2C1C4DB4E95070BAFD37C23BC37AD988913D2744C195976B0B52B7DCAA1BB31ABF59565876BA98DACE8763375362CA10E42568D68212413AD4F78682D24E3925C13CE6EBF23D2BA8EFF335 +ct = 33C8DC5381CC3CE7E50F82C66DA129B3C827A0657A577E0940D2AEDA06A2DE05DB3FE58842F6EF004DBF929A22AF309D0DCCBA66D6CAA8E1612D8533137E2730A94654A51E10B32513BD733A53915E827EE6FAC8A71F5D84CD5B64BBED011E749D96BFEC3999E2AB10281CE9136CF7C57DAC304EA259B3031883557FBF0AC9BF9F11B07A3903BF1CA77BE1FB4F716D5014F656B4615176ADF65CF1189B2B42D0482072A49197FCA56DD9460545D4ECFC9DB09C76ABA5DD156BEFA8243E0503BA20867B0E02A6363C8042C419A5EE8C8549C288DA90E1EB612B477E75BDC56BD50F858163F11D27E1BAE9E20B6160E1E42EC5CFB07E7908FDE9302527B53614ECE02451B61A9A26A9BED4D9C3EE29C60B0DB045BD9C4813154BEDEB77BBBBF43C908FA12516D027B95A67D43C0F811C809A318F14913C11E64DC81FA1541B1A4A72E93B6AE17687246D9DFB820481A3FD2E08E8F9CA4768F53E04B0328FAE2956B8E100A474023A2F893B5078E6C98F684168FA8397E74AAEFE32D23966FE358FE4AFB990D6FA7C9D2F7B74861367F0540818 +ss = 9272A0390B05170693287EB6A6A93CB28F8F5A49731F5873 + +count = 37 +seed = D882BA69AC8BBC88715F1C6387531F53273A5DAB87E66FAA8221A7F628D2BDEEE1CBC59C0E08D0ADD84520A3A70C1389 +pk = F81EA80547B4FE29D3A7353D31307C97AA173E35B90C0116645184E60262A10FD6FE042184803EDAFB1D53BA7BB9F1B17E9B37C50A1271E41A34469DDC962B14D40C093E76F2AD9D39F474F4D30D749CC4385A34CCFD305B385628BF6C539F97E5854A432E251FF170F31319900CA5C75867E69DAE733A89D39FF6356012CC26259EE970A6DF942EE5CC0A3B2926707B32D19B4589670FAD59E11BBE7FFE74D36DF1257EE0277A1C7015E88E32123F023CFEB6D33047E4A7D2BEBCB806B4705022E7D426D8D3BD69419B532EB4848541E0E60EB644A13126A2210B5D40792A74049BC77BBD41D021E8F94E5DA1D00E8F716D8B60623E29AAC7689A2EE2AC3D6953C1A036DD19CF470068D2362B4D0E1A416279514696207C723AC2069657C4DAF2B3C749EDC4E4CAF5BFFBFF5ACD8715B0E5E8F00CB1D711104D233B1FF22CE183BB22011F27156EBC7DAFF060F4FF7CEBAADC59B6062589C26728A3A4F13DF2706727D3F3CADC7CE80F475C902661DBC75DD0C627F437D7943F +sk = A1B52D871612A1C611AE0944F9E71858F35D3BD14F20E96A1F135CF64B6403E103AFAE34DA038613E2853BBFC36BAAFA3C6A95347193F30CF81EA80547B4FE29D3A7353D31307C97AA173E35B90C0116645184E60262A10FD6FE042184803EDAFB1D53BA7BB9F1B17E9B37C50A1271E41A34469DDC962B14D40C093E76F2AD9D39F474F4D30D749CC4385A34CCFD305B385628BF6C539F97E5854A432E251FF170F31319900CA5C75867E69DAE733A89D39FF6356012CC26259EE970A6DF942EE5CC0A3B2926707B32D19B4589670FAD59E11BBE7FFE74D36DF1257EE0277A1C7015E88E32123F023CFEB6D33047E4A7D2BEBCB806B4705022E7D426D8D3BD69419B532EB4848541E0E60EB644A13126A2210B5D40792A74049BC77BBD41D021E8F94E5DA1D00E8F716D8B60623E29AAC7689A2EE2AC3D6953C1A036DD19CF470068D2362B4D0E1A416279514696207C723AC2069657C4DAF2B3C749EDC4E4CAF5BFFBFF5ACD8715B0E5E8F00CB1D711104D233B1FF22CE183BB22011F27156EBC7DAFF060F4FF7CEBAADC59B6062589C26728A3A4F13DF2706727D3F3CADC7CE80F475C902661DBC75DD0C627F437D7943F +ct = 2E1B63993E248E5C93340CB2AA34F53CA33E2E48E24545348123589270C67E32AAA3800A7CD1C53148256145E739D0F03E2C72672D7BBCFAB77B7D9041481924634C3BD7D2C29EBFA649575E8E65C282E232A4BD5CFE2F0F58B6A2DA9A7A79C25204D54B23A4A6FCD27D888302F8D3F9E76A53FAF2DD508BF90C0D9DA60229DA69D1CBC3C3DD1356BC91425839EFBEAFF4F5115172D9A4FE552FD7E4A857A219E55314D5675E099D1C83AB79D3B62340FED2C88CD6F7648BE0B0BEE730651F5992A73AC85023CFFE6B665689DC785353B3127638F8B05DCE7418E87C6E542996930DCE1F19FD5F8584F139B5EA3CF2C01911E0169ED206F830F8FF1811D3A43009D5CDE5209FCC35EC27661D53F69B3797809E76F63646C8F099C7B0676E097BB1FF977467D7996469118524B4C0FD36D9ABFAC3D2E7C511A9312477E3354F26CD44F1FE150F23C6FAE0B8D384F0763137E59D67DC5C6D99159C74A88B4BFF3D8FC537682CF507309DD176901758FC49F2359AE390FF18D4E62D0A9001519EBA42B8BC13CD7F10ACD89BCFF06D214EDE7621 +ss = 72F6DA9DA867652E3E80628EF1D9AC389D41020985D0655F + +count = 38 +seed = 6C3AFF39F5D097096D882F24717718C8A702382DC4AAFFD7629763FDA73C163CF084807BBB0C9F600CD31A7135F48AEC +pk = 3168BD9D3C7E94423496B758FC6CA983EDF620A29D208DC4E3D9068C39E19C161508278609DA43D730E005A14F14DED29EF5EE95B394F1C7E202EEE9509B2B9BF89D16C80EDDA4020A45DFEF2F8B7E304E417B48C70987D3FF1E50C196766EC1A6C5640069BA6141ED8A934EC79CC42A7298610A88C18034D795A2C46A031C330C4F33F3758AE67005A26BCDCB5BFCFD47C5E127DEC06E2E4213256BF1DCBC83CCE752461E167F0FA646B0AEDBB3174C56BA2338F00BEA9474B464C8287B30F02274F10F84AE89E3BCE088603BBCE3F6BD17069B4784A52EDCEB4FC04838BB1E35298092D956D68E19D9FE50F59700D0E77FCB6CA7AAFCB138F7540E72770A7CAE27E991089C5C9661007FD4F01D7311C083402C958ED4EBF4379441337632582C23546E7D9E04DD6DFBDB7336F505FB14160FE9646C47B61D6306D13002B3006C9F4A2670786A4E04B992C8FAAC4E5063D85BB6A2D7454449F6D872C72B64F41800D888B22CBE1B6D93B45A2ECF6DA8088041CEE3EB8CAC2336 +sk = 952B49C803D6D6FBA69F4375ADCE8594847A00BCAE2179DA62D7033947AE42CA53522A65FBAFE18D3BC3E0CB66164E9A094FE4B44D89770D3168BD9D3C7E94423496B758FC6CA983EDF620A29D208DC4E3D9068C39E19C161508278609DA43D730E005A14F14DED29EF5EE95B394F1C7E202EEE9509B2B9BF89D16C80EDDA4020A45DFEF2F8B7E304E417B48C70987D3FF1E50C196766EC1A6C5640069BA6141ED8A934EC79CC42A7298610A88C18034D795A2C46A031C330C4F33F3758AE67005A26BCDCB5BFCFD47C5E127DEC06E2E4213256BF1DCBC83CCE752461E167F0FA646B0AEDBB3174C56BA2338F00BEA9474B464C8287B30F02274F10F84AE89E3BCE088603BBCE3F6BD17069B4784A52EDCEB4FC04838BB1E35298092D956D68E19D9FE50F59700D0E77FCB6CA7AAFCB138F7540E72770A7CAE27E991089C5C9661007FD4F01D7311C083402C958ED4EBF4379441337632582C23546E7D9E04DD6DFBDB7336F505FB14160FE9646C47B61D6306D13002B3006C9F4A2670786A4E04B992C8FAAC4E5063D85BB6A2D7454449F6D872C72B64F41800D888B22CBE1B6D93B45A2ECF6DA8088041CEE3EB8CAC2336 +ct = 377F2974A07068F15C2D52790BB996FA6CE5527E9EA3FCA8C9C6F61F0D4C952B3390F48706D9906E15392E4DCDCAFC88B4B99154B86B3A984F68360A6AC300DFE89A66D7DF0270DC98760C7BBC27A56E8AFC0473CBB850C290D1832EABE77BB4EAE8CE1E20BA595BAD597602EF2A8BF807D22B39AABCCAE623507C27DD1C80F579EB0D221A035630E3F0D499A8A155029618FFCFBDBA11326B60DBDC7AE70348D2F9867E277329F845A572663D1F4BA44680C0B9A19F49C5F6888B37265A6EDAECBDCEDFAD67D0C7CF5D9B25E3D625C9A024B18BE43BF309F7936EDEF1AD795503D6C100A5924753F1CE8FA06C27178500CA6021EFC319134168230355F53F89E93748DDB54524D3007DB0E4AB3DC12A4650C7BABF50B2C8ACA9BBBD9DB3AC5D4FC93EE1DB15412FEECAF348531475F43DC6FF03EBB5B494F9C3312914D8E4A025D7DC0DBE79858DF385ACF1245ACCC9F51A18C574DC3C5797BDD82A68C3DDFCF94E0CFB273CC6D0206B1AE9CD0D945736F1AF31545D79E7E32CF18585D91AFA9A697D22EBF6B0F5488480802B470ACDC634 +ss = 51114A60F9D0E1CBF25CA1A7E1CF78C0B38FCE11BEF7B004 + +count = 39 +seed = CF520B92A2E3677AFD003EC1EC6EF136A709D78F828C9C0DD4946EFBD451C5FAABFC83CA66F9D3D17EE4220553B7A69F +pk = 62DE638857F80F49FDC0DB09A52C96F0760F92876E7E6C36563D3A82E7A615CF8BF48D41EC208EA759D6DAD7277F31D0F9331C976F2A6876B9DF53B8EFDD3D5022E900154BD6A3B3478362454BCFF2BDA112597E11A9664504F1A645A7FC8ACAB3A54B1E1F112598DC1E7CDF30B16FE0F5C5D87962C93FE80112F5809002A9A49349A227738DA1E822D770F75566813A5A56D1289CB98E5F21E89B82B0E3337AE50A65E1A9C4AD6F9BCF1C65F1FD5F3837FE20677E37BDEC3AED33AB294B54BD693417770293BD433AF8D18D06A634A4DD45CDCFD37B8DDC28D672AA467B5794B0F0A1CDB05DE7F75BC45CD20120AC4D400D7118D595434B730B640C0CA7777A9DB119FB6A98EDCB1C1541829E580502CB25626A707E616F79B7F1CEC8B316A2B2A5C3E6DF6E57B7239D1471950B3701659E9F78A7530598C134372E6D78C2728DAAA369F9A1DC6E230A5A0F9C9046D48906EC98D47F81CF4F5A7F0D0CA87242E753908C7820801A69527928A1BBB6845DE6B1D2F0BE8C3A6115 +sk = 3C815E57E9233E975FA1630208AAB206B71AE0DB37A7A87801C8E376FDB140EE343106C093AF7CB149B316BA79446CEB4E5E0CEDB9B1640962DE638857F80F49FDC0DB09A52C96F0760F92876E7E6C36563D3A82E7A615CF8BF48D41EC208EA759D6DAD7277F31D0F9331C976F2A6876B9DF53B8EFDD3D5022E900154BD6A3B3478362454BCFF2BDA112597E11A9664504F1A645A7FC8ACAB3A54B1E1F112598DC1E7CDF30B16FE0F5C5D87962C93FE80112F5809002A9A49349A227738DA1E822D770F75566813A5A56D1289CB98E5F21E89B82B0E3337AE50A65E1A9C4AD6F9BCF1C65F1FD5F3837FE20677E37BDEC3AED33AB294B54BD693417770293BD433AF8D18D06A634A4DD45CDCFD37B8DDC28D672AA467B5794B0F0A1CDB05DE7F75BC45CD20120AC4D400D7118D595434B730B640C0CA7777A9DB119FB6A98EDCB1C1541829E580502CB25626A707E616F79B7F1CEC8B316A2B2A5C3E6DF6E57B7239D1471950B3701659E9F78A7530598C134372E6D78C2728DAAA369F9A1DC6E230A5A0F9C9046D48906EC98D47F81CF4F5A7F0D0CA87242E753908C7820801A69527928A1BBB6845DE6B1D2F0BE8C3A6115 +ct = F1AA58CF8236861636CFBADDD17A852AEA087B449CA0E95A646547DA41A9E2B8BDE763D81942AB72E8996AE97C31F8EC0883C06F2B1CEBA8594D8B7B54443901568777298377267FD272396863E0A6AF29B871B5BDF5182E96F28513BE8B0BD996FC6E7E4AE925523AB10320BA3078147BE06D5B05661629D459E5059C1048AECD5CED098F5D86AE70BAC5CE245C08D74D92B4BBFC8A512F8B227D2E6FA54E9E558BCDE57EF1458E8CF0EB15ED1F453D482ECA57C1D5F598A33A424D37E0A1BB0B8640AE450DDF1CA39440225663DE142A83541364E88AA151CBB5147A89396953000762C85DB36354CC97B3D3787F4BA6233715D43E5F23CBAEBE0C768381B03FAFA99516B0B64E192C7A9820FF2873CB01DAC0FF6ACC02D9531BF9BC43AA89F1FBFC9E5911E954CB620AB155906C607CFFE0C9036C2E49088C397B9CC151C5E8764E8BD630EA9BCE2C6D27B6822C5A4AEB0F73016DBC296AE9C25AA564B1887EB31EE37DBF6EA108C0CD85CB10A637A302037A5F5AE70D142A8C2B70D915FAD53CDB294FCF6A58AB91A00AF5105180FBE3 +ss = 7B624C0703A0A47F62C174681C0CCD4B6F031C40CC05E6DF + +count = 40 +seed = 197E5D562DE7E01BED4FC597DB28DC6EFDF0179F3A5BDA5F94CAA39D67BAE730540534D59A7A06C8448F628DA8B7859F +pk = 0F57DED59D6FF0F82D79EFF2DAE83CC9B75B29696B83687CA0925A06838A99A8157B17D384569CB11DB8DA003F921FFEB7D6FC59A44177A65A98417F7B64059CD40095B471ACEA5E06E972B9E714E97FDD6824E0756ED9439C720AE9BEF8CA6E47EB6CBAE61EC00F73E3035F9B10F14903296175334F9DE7FD452E71242ABFB77F74842F2480DCB3309E6536E6718A9E06CF68D477FDFC7405DEFA4AEC7644F1BE2104E53B4BA744759539B90CC7A30FE3A3357B7DF761F1DC657D191E5C9397F7190B7FAC16E3C22EAB251391426A71AA67467EB10715E8113C2B4608170029E20F390241E0432982CB30B6F0A7961B85D0BAED6239F12ED1983A2DF129DD86944004C22D6C1026CD83CD159D472CF91EB3A1ADAF36CD0EF720E539BDDA0E1A86E1B170AC4D29A026380BA057FC6EFFAAF49F4E599E4B207DE009A99B4CE6BB9233CA2F0FA912E50277AD683EE2509322A7C11AC0A7850BB5DB1101CCBD5EC894BCB7D8EA88AAF0EC52135D002CB930A7D90200EA219494B724 +sk = 588760826DCFBD36D9ABE6AE44A669BB3EBBA6A218EAB69E0E860576285483BB5FD36E2F944D32C4317BEBC1E441470C1372046A790D79040F57DED59D6FF0F82D79EFF2DAE83CC9B75B29696B83687CA0925A06838A99A8157B17D384569CB11DB8DA003F921FFEB7D6FC59A44177A65A98417F7B64059CD40095B471ACEA5E06E972B9E714E97FDD6824E0756ED9439C720AE9BEF8CA6E47EB6CBAE61EC00F73E3035F9B10F14903296175334F9DE7FD452E71242ABFB77F74842F2480DCB3309E6536E6718A9E06CF68D477FDFC7405DEFA4AEC7644F1BE2104E53B4BA744759539B90CC7A30FE3A3357B7DF761F1DC657D191E5C9397F7190B7FAC16E3C22EAB251391426A71AA67467EB10715E8113C2B4608170029E20F390241E0432982CB30B6F0A7961B85D0BAED6239F12ED1983A2DF129DD86944004C22D6C1026CD83CD159D472CF91EB3A1ADAF36CD0EF720E539BDDA0E1A86E1B170AC4D29A026380BA057FC6EFFAAF49F4E599E4B207DE009A99B4CE6BB9233CA2F0FA912E50277AD683EE2509322A7C11AC0A7850BB5DB1101CCBD5EC894BCB7D8EA88AAF0EC52135D002CB930A7D90200EA219494B724 +ct = B9FC8FF5F9F9A030E5BB25F9000090BE8FB2022F163E3753600035991C2D737125C110F7BBD07933F549EA3A6C43B39AE8A72E7F16476F77CC32CDD31EB80C05BFFCC7C38370D1D03D152DD80563E8B6DE4B1AD9D13E52E1C2F6B99F2ACA361B9BFFBE0CB73395D9DAAADFF4498A53F287EC8C861BBC531A50F8AC896608356751A3EF58B28E82FEF0B5B4D2855D91AE7365003D79E21E4FF13856F11C5E5DD15B6C8BBC31DF6E4CF1B870E75FB418E664CCE6C405A4654544F2A3120422255F98A53813FA5AB7DA3D316E1FC7D06C61E1E9DD5BE7DBA6DA6B4AA6FB959BCCD03F860B116BA8647A004AE3DE72B701FF15104CC7B0E6BD35E7235D3027A3267D78F475ACD3D6A6AA470480167CE34E2AA46D3E85DD6E19CFE23629BF12AF399A396CED23A74D8AAAAEFE2D4CC3506688E2FEF1064D7E88C23F10046015C3543C5EC44DA9A5F29BE5C78B055023EBDB1E0498D2897C9C82B90A54A6178A1CD4718FA75115FBC1DDF657E7C847819F2A1599E9B23DBEB6B3F665128AB0428F5686FAE5F792C054CE2EF830088CC2E3085C81D0 +ss = E33DDC85305ABB33EC79D7B3FD5DAF44F4B620B6F2F044CF + +count = 41 +seed = F170583CB451D8A45D105457C02C01A33A40350616ED8515BD49067142F61EFB00F07857E4FFF3FE11E7164C648C76ED +pk = E66D9ADC7D9B147C97F811B40464A27E2999A3388B4861910055709FF732AC417D3A4498B142792899934D4ADF57550CDBBA197EB7C58C9E35C15B7E91D33595D5493D7F3E14F2498D5A26676F468C0D0C04ABE6233556ACA23ABB6A2A2F7D44EEA82A0D8129C3A887EF6D848EDBFCC0EC06DE9617EC0B92B173CB87211395920D4EA2A1585665AC8BFCEC32475BC099A2A9B4353EDE3FFDD1490810E9EFBC0971ED5379DC0547C0C645AB184035D75971FAC9BF4E78CEBE73D89ACE061DE7CF2E29B118024D63E2170C6CDE6511A56C4ED7DB2C713ABB34564087475B9A2A568DFE7F60435D02657E0B48914083DD7B5EA12BFFCF510646FCA45E140090E643AAD17F33B74096B9303F1BBA1DC4D707D196FE8DA39E7E4DCE0FE26DD85534248D66687AC02B99702279328338C43CA27C55DC06EC475171C69D1A644F2D4671628E093882BA1D3FB5F2F4EA453B4A83A2DB83835FAD683701A7CC7DA6C99D53E4095137DFB6EF7445E2821A1761ADD580BFFF4BF6A486C64C24 +sk = 47550E9EDACB6DDCE3D9AB81F6B61080DD4F2693854ACB05F89D7D99D5C3E0D10D6EF9AF054D842375F695ABB28E3B8EB495100F04306E02E66D9ADC7D9B147C97F811B40464A27E2999A3388B4861910055709FF732AC417D3A4498B142792899934D4ADF57550CDBBA197EB7C58C9E35C15B7E91D33595D5493D7F3E14F2498D5A26676F468C0D0C04ABE6233556ACA23ABB6A2A2F7D44EEA82A0D8129C3A887EF6D848EDBFCC0EC06DE9617EC0B92B173CB87211395920D4EA2A1585665AC8BFCEC32475BC099A2A9B4353EDE3FFDD1490810E9EFBC0971ED5379DC0547C0C645AB184035D75971FAC9BF4E78CEBE73D89ACE061DE7CF2E29B118024D63E2170C6CDE6511A56C4ED7DB2C713ABB34564087475B9A2A568DFE7F60435D02657E0B48914083DD7B5EA12BFFCF510646FCA45E140090E643AAD17F33B74096B9303F1BBA1DC4D707D196FE8DA39E7E4DCE0FE26DD85534248D66687AC02B99702279328338C43CA27C55DC06EC475171C69D1A644F2D4671628E093882BA1D3FB5F2F4EA453B4A83A2DB83835FAD683701A7CC7DA6C99D53E4095137DFB6EF7445E2821A1761ADD580BFFF4BF6A486C64C24 +ct = 19EA87EE0A8122652F4D42D5542DF61530D9FDFAFCB86552CB60D046A094D7FB418522EEF60ED25C47362B910CC481640867F04B0D3DABF72D5037E1F7761B0C289FE2C4B230EB5E099C88304118DC274AD5AE3810B88E3AA7C51AB25407EA05A03151FFEC95906B6484263F44BDF6B39CC842B48A3499916216ED204B02CA6D23AB224DBA215733A65BE624360433D7F0D7B1FA37127C5D60A512ECC33C572683E5003A8EA6CB8B033AB9CCBB257A6BB219F6ABFA6F44931C9DF89D38F26AA12F2B417DE95E21F06EF6C0A8DA72A09B26B28D8A0C041CC80DB0CCA9F6AA579CF539E66D982DC860CB25077AD8244030799E932A96AE2A3E5620F302AE72F38C57F8425F52927FB51FC963159111C2079061B64D6F56EAA664748D39F47B2A3EC4FE4D2AB8FF161F08A9D6DCA932CEB281AC62C69658CBA6A2DB2F9E849FA4D960ACA3E0DCC8B75F80EFE77873CC22291BF00D26501F9BE857E63F1320DBFF3D747788FAAC38AE51777871293B424D45DB4978276948CAF5330CAEC3921E6E6DA98B993A93297F3ADB0EA27B9A8FD3C51D2C +ss = B94904EC21529938A5A4651EA576E0372483E6ACD980767F + +count = 42 +seed = 44A6774B2CAC02DFF210FF861A090561A453DB311F47B6FEDB81811872D5D9489F5FC4103010139AE53FCAED209DC9BE +pk = D3AB35DB1ABF9CAC97BABFBA8D055A6AB7468BEDDEA1F4BBDCC503F729E4D82946F34A307C9939DF4524F43B4517B0358E545CBF21BB167899E5E099BB8916CF454B6F97AF4252BBDE9061AEC58A45F7FA8EB50689F87F9BE7F322F0A2CB1E05C8A94F9535615399CFD0D4F56BC9ED6F56CF4E8ED2467E9A4AB5396D7F03A148FD31B8A9D965B223F1B91B862127614C2C1E97F0E86EDC55839CB7640873067396EE224BEC416A19F283089609E68B400DE1A14081D292774D69907F0865D03FE408B912CE188EE2AFDA92ADCBD6158E0E015BC99062A668EDB0E22E28883F40910455927B2D2CF2451F3A722FF19CCEDE483F7E6DCA9FE02430640B2FF863B441E2BD68894515A6F2D54A9CB0D45EA47A3B909EDCB97857611266E92016F961757D6CB9B0A79E84CA5938EC6DD0DA699EBBB1DFF36716F5422600B77FA100434D4C3048638436C622070E19CAFD089D3FBFB9703FB54D3D45C27906F1FA00F3DBBCFA523CCA4C26A3CD35D634383B703A60E11CD4393FD33902 +sk = 610AFB64BE8CC1DF288CFB016EE2F44C6C07113DE7F6FEE0CD292E4C5F9E1A55E0489BCEFFB204D672A6215F4F3980A646D9F880817C520DD3AB35DB1ABF9CAC97BABFBA8D055A6AB7468BEDDEA1F4BBDCC503F729E4D82946F34A307C9939DF4524F43B4517B0358E545CBF21BB167899E5E099BB8916CF454B6F97AF4252BBDE9061AEC58A45F7FA8EB50689F87F9BE7F322F0A2CB1E05C8A94F9535615399CFD0D4F56BC9ED6F56CF4E8ED2467E9A4AB5396D7F03A148FD31B8A9D965B223F1B91B862127614C2C1E97F0E86EDC55839CB7640873067396EE224BEC416A19F283089609E68B400DE1A14081D292774D69907F0865D03FE408B912CE188EE2AFDA92ADCBD6158E0E015BC99062A668EDB0E22E28883F40910455927B2D2CF2451F3A722FF19CCEDE483F7E6DCA9FE02430640B2FF863B441E2BD68894515A6F2D54A9CB0D45EA47A3B909EDCB97857611266E92016F961757D6CB9B0A79E84CA5938EC6DD0DA699EBBB1DFF36716F5422600B77FA100434D4C3048638436C622070E19CAFD089D3FBFB9703FB54D3D45C27906F1FA00F3DBBCFA523CCA4C26A3CD35D634383B703A60E11CD4393FD33902 +ct = B6714EB214580F660B63E7A69B0650F5FC11249AAC2E9A77607921B8B684611CDAB05E7B702E4D16B8DA26290E419E16A5E5C09ED396CE9AEC7019FF2FCA18DD7591BAFEB001B8ED96CB4297FDD3FAD2B9E89C73868E3E616C5CDB3B44E06FE789C6AAEBEB898CA6281FECAB9B516F7FC296710B02B83E18BDAC3C46D51B45FD79658A9C2D1B726E5E330D1ED837D8565BA457CE948A549E71C14E25D7F14CE5F09644CB02E36C5E813BD2B2683279B3E332BC36F0713CB1FDD2F3150C4520A7F21A5C256B0E3997BA5A360E098B582A3FC8C819F8D4C186F210F269BB52B0E5DFF3A4A56D212560ED61B95258BA387408A2AFE6766E89F72505C000558FE7D145A9C56431778F421D58469F59481E0C06AA0B9620A1675A6BD8988EB24EFFCEBD254B8B35246B659A8D6DD74936F0B6169F803332D7F7924FFF0AC4C6AE14A7D0EA4CB384F381D43E17094EA3F3BBF0630D2838A7D05564606C6BB039C2B4624E1903E4FFB096B7B6CD5E6EC8EBBA250D14195448CE96E7C41DEE00E00A470F389D6EB36F69D35ACB8608EE2ED9069BE028 +ss = 4747804B324F5E1700861C0456762F30839CC5D9D7A3CBA7 + +count = 43 +seed = 49E1855588B6235DF2A400C4A70AEDF8AB17B6E5E2891AA745F132FA2E7AB0C8117C1DF37C39F5D57624EB77C2B4A091 +pk = 038C8F14B1756E747DD9239148DC4929C769FB182651E7CF5E566D91CA82D812F4AB5871CBEDDCFD4B3D79F71302DE3BF0BC187D9640E0020E7D7FA6EBDF3650323E9E6DDECCB7E459643E55464948CD65CF4001F9EC92BA61C468E09237BE8A1588B7E6B4C2AA9A4768360E28570CA2286559FAB5F86CE8629C6EEEA2057CDB07D4A0F2C8D7ADB90C19C8FBD4B671C0ACB87F50C29CDB5DF7BFD09156075A8C5B12292239DEE8ED686738D28843E7711D105A5037F27BE001FE9F092A75665B63996DF1C2032DA93B7181AB0F81357A84C90B935ED44172A00A7EE0B2C42E1D011B2A095EBEB2C8924FB67663AA7D35469E17498915A97CC89A4B3FFCB705E6B39FB5C4466E2AE27F94EF10DE3D083DEC766C068D9956D9E2146246445EC163DC45473B902F791DF2017D372CB89725A238E3D313D274DD47C03E7D64DD003205471E0A61E92FAD595D022E06E9E7A9D16761FE3D69C3274287464613134A250795DC73D6F6D052660B0F329A9DC408A6F94F334789BBE3790C +sk = E1953800ACAA85AC02A906C72CB8E8D704E8D27820345F888C64C049C6DFC0F1476CFFD520B055756162F7EC94243DE6B14AC0B9E5FB360C038C8F14B1756E747DD9239148DC4929C769FB182651E7CF5E566D91CA82D812F4AB5871CBEDDCFD4B3D79F71302DE3BF0BC187D9640E0020E7D7FA6EBDF3650323E9E6DDECCB7E459643E55464948CD65CF4001F9EC92BA61C468E09237BE8A1588B7E6B4C2AA9A4768360E28570CA2286559FAB5F86CE8629C6EEEA2057CDB07D4A0F2C8D7ADB90C19C8FBD4B671C0ACB87F50C29CDB5DF7BFD09156075A8C5B12292239DEE8ED686738D28843E7711D105A5037F27BE001FE9F092A75665B63996DF1C2032DA93B7181AB0F81357A84C90B935ED44172A00A7EE0B2C42E1D011B2A095EBEB2C8924FB67663AA7D35469E17498915A97CC89A4B3FFCB705E6B39FB5C4466E2AE27F94EF10DE3D083DEC766C068D9956D9E2146246445EC163DC45473B902F791DF2017D372CB89725A238E3D313D274DD47C03E7D64DD003205471E0A61E92FAD595D022E06E9E7A9D16761FE3D69C3274287464613134A250795DC73D6F6D052660B0F329A9DC408A6F94F334789BBE3790C +ct = 4DF254033DA961CE2BE002A15368DB46140D868AC61FA42B700B6B2FE002F90E45AA7539AAA170798936A8E71E460C7E9635A970F39E364518BC16DD660039BD7A82A2A9AC4D716731A03081788BDB4F37FEF4F7CF2EDCCC77E2385F79F2B411FBD0E43B7DD1BF8A453492D2633E3ADEEF773B64F6BACA9A38694C18373297B39D66803A11405CE1142F8FB4C854C1028D206D96912FAE14E58583BAC5DDA7F0DAFEB711F729BC7D275508043F8A5DC2B00BD766DCB5E90A4F2F3A631A4906465525692C1A7040D81A4B3294DE0FA568B4CA65CCEF3FE5B40DD8426C36DD6A11D79B7B12FA6F9010CA79605925217742E45A8909AAAB169F1E63A303688194B8B836073DF9B5CA70FDA001C449759B115EFA3381B4AA6FC69A2F6EA13A261A456A58D734EEA825A0F61AD1CBDC5EF9BD626441DABD5A7FB94917409E01EF2AF8C8F4C7C31FD5D134874B25AD94B3B390DC057372E406C77C96E509E0A38C95F8EDB52C4646362AAC44156A7DA7A174C10112479ADE0870AC0613D2A6126998BC71C9A4E7C5DDDB7B9C4EE05BDC150B65BB8C +ss = 841903B25A4F1A31C10CBD2357067D22EB25DFC04C58AE38 + +count = 44 +seed = DF0E41D2F6F86C1F79D31FD5878E7AB434FC0AF3A0D5F47D2AB3FEF31A42BD949B0E3629DF9F575BEFBB62E829E51DAE +pk = A9089A7E83D5F9356FD075919B61D2999F42EF4013D2825AE223C0DE56CA729D66BBC5F5C1CD6088C71E7EAFC85C28CA8A1048EF89788CCB1DBF5934CDCE336FAB3515666129140AEB7698E43BD9D3C7346BA9BD503E7BCE6E3A855BAB3B9D63FF3184A476903DA27137AF4B83683DCC422F9544E627E0223B9E580D7E0029A67586039EC1F5C17A3873248637C59EEF3B00D2147E055DEDF4E6EE9B67C24C9DA6B0D1006E1E189F9009A555B8D41A82E63925C0815FC70FA900F6D1004CF2D5CC4D500AFB29B63EC1EE570A459722508F39556C26432639A2FF046A617794C7DAFB82425049DB1FE24C2F537FD127D01037F797BF281ACB25E21F3A5190B0CDE134DF7A5A20F64C6B09B20F784B03AEB3500C061CA89E93E0BB32E52BAD5F2F7EAE21A5CC1E077521BD3247E3C0AD3012752EE5BEC5639AAC9531236FE5F2022BAE273DF4D1C03E4C46AC93770F382A0C9D44BAE0FE60F5CB0A95B5278C411C3F6E0113144CBDA040A8C33BB63C219FDA33FF9E2933BC1DE535 +sk = C719F9B2D16399B7326CE4ECA30DABEFE8FDAAB18E9F6DF8E40771856EB77E4633504899FCB86C6A3D433D0B8D60E26F07BD61F1D4ED690DA9089A7E83D5F9356FD075919B61D2999F42EF4013D2825AE223C0DE56CA729D66BBC5F5C1CD6088C71E7EAFC85C28CA8A1048EF89788CCB1DBF5934CDCE336FAB3515666129140AEB7698E43BD9D3C7346BA9BD503E7BCE6E3A855BAB3B9D63FF3184A476903DA27137AF4B83683DCC422F9544E627E0223B9E580D7E0029A67586039EC1F5C17A3873248637C59EEF3B00D2147E055DEDF4E6EE9B67C24C9DA6B0D1006E1E189F9009A555B8D41A82E63925C0815FC70FA900F6D1004CF2D5CC4D500AFB29B63EC1EE570A459722508F39556C26432639A2FF046A617794C7DAFB82425049DB1FE24C2F537FD127D01037F797BF281ACB25E21F3A5190B0CDE134DF7A5A20F64C6B09B20F784B03AEB3500C061CA89E93E0BB32E52BAD5F2F7EAE21A5CC1E077521BD3247E3C0AD3012752EE5BEC5639AAC9531236FE5F2022BAE273DF4D1C03E4C46AC93770F382A0C9D44BAE0FE60F5CB0A95B5278C411C3F6E0113144CBDA040A8C33BB63C219FDA33FF9E2933BC1DE535 +ct = 116D0A605866F99E49B19D6B6F34CE5A830D07D472E1CC6E3DCEC4A503C79BA503E0D3B54E3BF6ADD464C043243EAEFDEF4C437E160592A78780E0CA87121C7BA8141CCC70B8F60916CACA7E2EBA276C3181064523DC2089D0109EC69C7CB8095566E29B030DDE04690E4E5913919AA169BFDEE0E9AC3941D7898CD4AA250C5BBF1726267B785091309439EB3B6422CC28DF833D662D59D304ABAB55FD54C1D1B779C71C0FED2C514CBC87B169612C4A1A689A76EE210B76B1126F85050D38D9BEE810093206B177EB7194C5FEE4663849B70C1026D0CA39C6DB0197456C7DB43077E079389A6F33F65DD057CE8B3A218937727A24C1CB676B6C8D0335141B68DF6E79C20E1BFC2A7582B8C29E7ECACFA39C3D857F0E74CA7F3A9B058153199DB04C9EC952F4733C0F6A0D881D818CCD6DC4FE8F3D62BBC3A9BB178D1590DF3F62DC0514CF7DCF9AEC3238400F3FBC5A5607FC71FD2A27A08E92F93894671E80751907CBB77D46442B4A19715744A7C3DE731F0440039F19FD0E8C8E57919B3FCF3A8480623859A29617FF3ED0553C396A54 +ss = 55501CE296D88A5A9C9C962B05C7562B8924ACF2128AB352 + +count = 45 +seed = D3C9EBBA6EB03CCB5C9B9D2C8D7F0CFBBF50841E24396CDDF0E56525B38918C2FBE6C34CC1B93F7BCD4F4D5777E1A488 +pk = 80A37EDEFD93DD1A35BDD6E90B5F51FDF3CC860F860A32E6EDFB90514B60C56C0C2D839C9137007368954DCC540B37AA8ABE36827BB7280585FEE0E861E70D3D87B3706D1246D8AE2453F5D021E0A0939A38D196C9A4DBEF323804AF7DF84E8E6EA090B109C528505DB1FD30F6DEFF83391AD8E4C2E135B3B82ED01BED3DAEE49A37A564B4DB21761102540D5102D578F9952BE900DEC9951C546734610BFE90CA1AD00C45833BEE63DF1ECE85AA2ED3CAC4AC6CB62DBD1A6DEA51150B54AC63A631E4495587EAFD3C1DF815C89CD72237620F612A44B9C3664FFA2F4D0CC26E8BD74243D353BDFCE4202566AC51979E34BDDE7F3529990750EE780CBEEA79D3178B3A7435F666477D5CBEE634CF07B90BE80D5D2F2FD9A84A62A4BA313C3D4014702A63F85DE8160D3565655964082A92223B62A846209F58D412F44D5C24BD63CE042E2A2EB392BD3BE00DFCFFF1C75DCE41BE2E9060C0EBCF75F5B1685CA0A563094AD3FA7C34C287384E41063EFDDA5B5F4B733857414A32 +sk = E9ACBB774BE970206C3A738E243B420805A509FA59FA9020DED5EDAEC5DE3BF5B4D7C2F2E18E87F499C1968993EFF196753DB8045E2C8B0880A37EDEFD93DD1A35BDD6E90B5F51FDF3CC860F860A32E6EDFB90514B60C56C0C2D839C9137007368954DCC540B37AA8ABE36827BB7280585FEE0E861E70D3D87B3706D1246D8AE2453F5D021E0A0939A38D196C9A4DBEF323804AF7DF84E8E6EA090B109C528505DB1FD30F6DEFF83391AD8E4C2E135B3B82ED01BED3DAEE49A37A564B4DB21761102540D5102D578F9952BE900DEC9951C546734610BFE90CA1AD00C45833BEE63DF1ECE85AA2ED3CAC4AC6CB62DBD1A6DEA51150B54AC63A631E4495587EAFD3C1DF815C89CD72237620F612A44B9C3664FFA2F4D0CC26E8BD74243D353BDFCE4202566AC51979E34BDDE7F3529990750EE780CBEEA79D3178B3A7435F666477D5CBEE634CF07B90BE80D5D2F2FD9A84A62A4BA313C3D4014702A63F85DE8160D3565655964082A92223B62A846209F58D412F44D5C24BD63CE042E2A2EB392BD3BE00DFCFFF1C75DCE41BE2E9060C0EBCF75F5B1685CA0A563094AD3FA7C34C287384E41063EFDDA5B5F4B733857414A32 +ct = A3C8FF75002902B4350863A5D2E7428B9EEC8560E2912D31F3018CDC7234784B60BFBFE2F2125309D78775A137C7417E07EFE38BC86D79CCB48E871A940D113EE1E57A87FCC3B08BDEC0BB59669D5F43052A68897043C9E9ACDC46D285C7632C957C8567AA073832AA1BBDAC36B7E2B2A10C6ABF588D9A96D670598E5A0FA3AF9E3C1A34906D86C6AD02C0E4E265E178D97243D8CED410AC0CA68D25DC08B8D9919BB3F8C1914AAA0E3D49E217D3D7C58690C08ADE07684A73A4265A2F4A9B67D255B9E1C83A0807369BDF540F4A4F33D8B8E1767CFB598B6EF13CCED2FB06DD8127F5EF9D42997F9A30FA4CA4E4ECE8F414C26AF994D178B56A5734178512F2C83BC5CA698403394E31F66AF04289166C0E659A3AB0F3B372CC5DCB26E0335F03D5B441F56EB8881C4E911350A6C487FAED1D4E48D2151241E7003D0F12B2DA27744596488AAB57E4C5B2EE221625F44ACAA8778B82E2D3E3EADFD18D9E2BEBEC29A1A874C6C62EBAA3D111D976182634903C56FA2CB7B6920D23BB9DCD152DDB8F4D2E4E265B1D80DE5E2725557889D2BD +ss = FE6EEBD0E2902D868889C1C39A0DC8D1E85B5DCA4DB880CF + +count = 46 +seed = 6B3996E8BC6F52879F2B7BE012C44AD555707CB7E5FD8ABB3457A298336D6FDC9EB7853008FF13201D5969A315C7E493 +pk = C2BCE85E112FAFCDC1327B624AC82D2572B73930F7E0F5F81247376356158F7387233F845674DDE0601988EB30720A83C3E58138194C9A05ED9A1C5E74392725B8907B2B90A5B5109A043A10E91C762DF9FA65EE7E0E370A55858D955DBE9BBBDED1160487B7A12D8E3872858AA4E938D07328E217B03A4264A8711FFB1EF9091C617910BC74219E5383F99BA96BA253E6F157E3CF5925C3456B10FD00EEAA03F21D7B97209F805A31B20DE89A30C68E504F51F9DDCEA61CDE895CD414CB291948A1D58D73F726C329121515563A60C48223246A209F782FB757F547E55610D454D76BE1CF88E35D9FBDBA99C4E7C0689CA659421C33D7575BA059368BD8EC79F67A76664A3D2D6293363262DD9E5E9222F9BBB1F3AD0AA9B48742333D532EC5C2F91A64D8E73AA17E04A0CBC37324E4F0984047012B6B81B6AD0B1521C855AA501005D4FD5BFC0C09AC4105E506C27FB54076EE270E3DCF93A9B2D4B2952E19EAA6206EB60237B9B2BA235E6D822E494F6C897A14A91EC13820 +sk = C1B3CBFFAD4B306F9AF0CDD3028876486DBE858875C9B6491C96249919CEDC2369D8D739AB125E0D2CCB82DFEBCD90240A545CDFE0751102C2BCE85E112FAFCDC1327B624AC82D2572B73930F7E0F5F81247376356158F7387233F845674DDE0601988EB30720A83C3E58138194C9A05ED9A1C5E74392725B8907B2B90A5B5109A043A10E91C762DF9FA65EE7E0E370A55858D955DBE9BBBDED1160487B7A12D8E3872858AA4E938D07328E217B03A4264A8711FFB1EF9091C617910BC74219E5383F99BA96BA253E6F157E3CF5925C3456B10FD00EEAA03F21D7B97209F805A31B20DE89A30C68E504F51F9DDCEA61CDE895CD414CB291948A1D58D73F726C329121515563A60C48223246A209F782FB757F547E55610D454D76BE1CF88E35D9FBDBA99C4E7C0689CA659421C33D7575BA059368BD8EC79F67A76664A3D2D6293363262DD9E5E9222F9BBB1F3AD0AA9B48742333D532EC5C2F91A64D8E73AA17E04A0CBC37324E4F0984047012B6B81B6AD0B1521C855AA501005D4FD5BFC0C09AC4105E506C27FB54076EE270E3DCF93A9B2D4B2952E19EAA6206EB60237B9B2BA235E6D822E494F6C897A14A91EC13820 +ct = BAF11C6F58CA328A3CBA6743C3DF7371335C9047CE6CB7F1E5C1D342DA9010EF222A37249D9408D77A1FBD8B26F8FB8A681F836500B85B01014E6D26D45506DC6C2E103530D35F9185EC700DB7904A6C53ED90D60D4A2AF78385EEE2CDA9CB55C9EA14244ECEC1B8F437CB80D3D442E62D75B6B29AF36F1D6DDDDCE30032920F7C56705E5B86FD6D3C69975529A4601ED42029679F7789BCDF3016DB37CD48BF2A871047B47D515B4EA9D3EE51730C6742ECDC32CAFDDE48FBA5B461328CE04C8C5DFAB414E80ABE73CE01EED0873CC1FCD6640DAC8C84BD46F9F4F80B047C14633342DCC732AF9BA5F0862DCD4C4A6D106041A170395C6B61457A248F52F58A666083ACAD5281B1D16E50733E37585592D63F86AF6923ADFDA9B7081E85D77A63B3941830E15E25A5E1A7023076E07BE5988CC81B8ECA666883062E8ECF7CC5B6F65D3B824BDF3BA8FC20BDC9BF81EDFAF4A30E7864790D74780712315601D54BA7F97743B45D437B9C182CC76CDBC1B759DD0D5949E9E3EC3B60AFF1D82735CDFDBFF7C9CCE232FA6062FEB9E3CAEE74C1 +ss = 2B4F3F6BA7D91D8FCA27DBF1B57B8949F1C90D369C619AD4 + +count = 47 +seed = 730B65ECE22DE27D573CE3AEA7CB021C415DF210D228808D91D4F380070FFCB0778B683C71D4853DEB569C822765F2A3 +pk = B5BD5E6D59690C11DB4ACCCB1C5D67F066CF2A732A69A2FB0307019E14D6EB0595065D76C5285A9104F5B9BABC94571F407814F25645A992FE94DC57514F0319C22A1F81C090AFAF0B2EFB79A556549B44F095F40002DE2CA1C0FD08B3EF3B42F449B615EA2DD0A842DE6E7CE0C01432833796C0E84562AD328F99083716780CE37468793C24619A0FD3CEB900ADD3B128E3563C10F34E1B6450A822A8AC5A955A46811D3715D8BC4A811EE07F036E1AB2F8FB80EC89AE6F70E5ABE22A5CF3FDC623DD188B628D32FC2C198090C45EA4E9CA6CE8414B01DBFC0E75C616FFC8A3479D4F22DF4812D61943AEE6A555FA79EC8E4FCD94137B14E514602301B548D18A0525E8CEA4A6502606276A51DFE94398EF989BF0CDB738A8C26A81C264CFD2AA1EEAF089E366528DA64B7E8F6C90108831F5C3DFC8875D907222D116912027AE175A6B436B672D742B6F6E197B0464747C92EBE89465C29780293D8BB9F566AB849BDC7851820FBB3F56FBAAA3895624226F86D25C41FA1B00 +sk = FF7495B8575B5A98E4FD21FB4C3E58CBB60F14BEF21AA74CBDC370460375A778D1A31D01C42B66367ED8D9E8F84551002F552F0E52102B0DB5BD5E6D59690C11DB4ACCCB1C5D67F066CF2A732A69A2FB0307019E14D6EB0595065D76C5285A9104F5B9BABC94571F407814F25645A992FE94DC57514F0319C22A1F81C090AFAF0B2EFB79A556549B44F095F40002DE2CA1C0FD08B3EF3B42F449B615EA2DD0A842DE6E7CE0C01432833796C0E84562AD328F99083716780CE37468793C24619A0FD3CEB900ADD3B128E3563C10F34E1B6450A822A8AC5A955A46811D3715D8BC4A811EE07F036E1AB2F8FB80EC89AE6F70E5ABE22A5CF3FDC623DD188B628D32FC2C198090C45EA4E9CA6CE8414B01DBFC0E75C616FFC8A3479D4F22DF4812D61943AEE6A555FA79EC8E4FCD94137B14E514602301B548D18A0525E8CEA4A6502606276A51DFE94398EF989BF0CDB738A8C26A81C264CFD2AA1EEAF089E366528DA64B7E8F6C90108831F5C3DFC8875D907222D116912027AE175A6B436B672D742B6F6E197B0464747C92EBE89465C29780293D8BB9F566AB849BDC7851820FBB3F56FBAAA3895624226F86D25C41FA1B00 +ct = 80ED2D68CE8086790DAF044175B8819A93460DFB3F96F5906F29DEC8DB5464C5E3E546CAFFAA59831815F655823131973813AC7B264CDC262B7E3243A67B027994D1C0E0C6ADF89A96DD6BFA18BA6249EF635E431C46FF5374B9D2302EC2D43AABB110E8172ADD9A2AE9A9CB7401601CB4F43C5C40941B9B2185C061622B87F1C92E788A71F049FAD4F8E8A39F4A2250B4E602BC087FF957942AC855FC85FA56AD18871899D5D77CBCC220D160576D106DC1636F5A6909FCCAC51A2D1AADE5F7330DB5995F91A26DA65CA197DC09B348E72C7464BF80E7AE9A1FA345A5BE17364D2C210B3889EF9DA209CA6490D4E25E7FE3750184C6EFA46559122D4926B230B44A00A1FFE00FD1E50D880EA7EA0C351E6DEFA18F33F58892B3FBC8548C62F2A0D846E5F23B9246C2F36D90D71700B16CDD2FD854809BCBDF6701E669E46C442B1E70BEE0F0C11EDD853936AF3B55D0677E40E9E8E4F83C8DAD6BFFD2889D881AC1818A1509A1CCBD189AA9072C9F1D3F89327C79062C26BA1D1BA503238449D5B536CDFCE6CD1214F45A71E27395DD9269 +ss = 4770EAE83744168254FF4CAC72D7A3E9624CFB7AEE0187ED + +count = 48 +seed = 5522A5A891A9A9B5514F4556AFD8DF40B9CEC63A01492F0CB8A1DB073A285A963E4A9FF2376C88662F7D8D241F8ACF17 +pk = 9A15E09175DB223CA75B382C458FA086F871CFCC836532D07EAECD450A6197F77194437953436662F60AA7F4E9E9D3A64A20FE16FD623D562C06CEE12C5B221D042D0D783E323839F96C5800B0A2516CD16196C5A7853EF84CE869C7294A6ACCEF578141A9F60AD5E7BF84EF4802B0F3D6A8AB55CA90A87F88663A98A425E567FBA8A3DF33A4E8CF824D00BE7D6A7719579269F9ECC64E8A2A3D652DF7715BD87C372671524BE0B70123EAFA89537E44DB72A9B202DC944D81E3DEDF1F262CE1CBE1C5AF8EE88511453925F76E1D16B98C5964BA32E0DCF36E8EAC617B255F2E483418D3BD12CE91F02653FBD6F36F358F0C8B10897BFC0F03A378316C795620CC267EA66949F6AE6E0CF5C52C54AFBA28B17F774320B1C8B64D678BABD46E997EA0E3F0B25746FEE91A8E3F054058C58D8E4989EA5D35C1C4132C75555A21B93B64E75D1DA832203346B63FB17D98695DE9E7D6301179282B6AD2268E96F0D0FCCD3463D335C0EF947C1209FF4D54E6E88852538F73D4B3F737 +sk = BDC3FBA1C32751139FC45BACFFB3EA97F26573D804A5F27AFD5A08F656A6EB8CD20679930A31CAA6A6331C4B133A6838C223EF9F769F62069A15E09175DB223CA75B382C458FA086F871CFCC836532D07EAECD450A6197F77194437953436662F60AA7F4E9E9D3A64A20FE16FD623D562C06CEE12C5B221D042D0D783E323839F96C5800B0A2516CD16196C5A7853EF84CE869C7294A6ACCEF578141A9F60AD5E7BF84EF4802B0F3D6A8AB55CA90A87F88663A98A425E567FBA8A3DF33A4E8CF824D00BE7D6A7719579269F9ECC64E8A2A3D652DF7715BD87C372671524BE0B70123EAFA89537E44DB72A9B202DC944D81E3DEDF1F262CE1CBE1C5AF8EE88511453925F76E1D16B98C5964BA32E0DCF36E8EAC617B255F2E483418D3BD12CE91F02653FBD6F36F358F0C8B10897BFC0F03A378316C795620CC267EA66949F6AE6E0CF5C52C54AFBA28B17F774320B1C8B64D678BABD46E997EA0E3F0B25746FEE91A8E3F054058C58D8E4989EA5D35C1C4132C75555A21B93B64E75D1DA832203346B63FB17D98695DE9E7D6301179282B6AD2268E96F0D0FCCD3463D335C0EF947C1209FF4D54E6E88852538F73D4B3F737 +ct = 5B2C2D521E4E57B87D24C1DA1241B8339B145B6DB461B7C9DC6FE4E26BC8FA28A0C38139A688DF5E38F3313028FF21A02185BB25313F15D8E20173AB86620CAAF16D7E75007C22266FE6DEAC00F4542EDDF3D93659FC7FB31EE0EEF9D6437BA0DA1F80D33B1965286962D5CB3F584A136D9CF116BB38AE7D9071DBD9ED07DF7A7C1C23B7712FF9192758FECEBE5237CF4A82EBB1AB2468B98A092473FD3E9E36B3EECEC9DE542E11AAE466FBEA650D814F80C44AE0A999793D13922D06D7C8CE5995739643B42B29765E9B9A2CEE1B0C7AFF7187D8936632FA862CB876A2F228FB7D025D866BE5C01A07E6BAB2A649BC4730F20FFEDE4B35C7575A0C9BA755741F54180E5746CA37E8B8B2AFBDFA7E2BC331A38B42F48E68870A2F355D2F59B9EA49FAAE7F7EC0D282CBFB6C37417AAFDDCEC4978F17C38C35DA3F7F80D1210FD640B66F22DF78F79AC99779FE9718FAABE735CE49C7BA1CC509B335DB105F1378560B073C4A2F786796C3A9634963F72CF76AE6D03260C93819B8890AEDBE6E9FB4592E2C0BDAC1FE51493A9E462665B5FB +ss = A2791C017E6396143C0DEF06601118E458FE5A975A6871DF + +count = 49 +seed = 1853E72329353B3F89AE6A1B1EF700DA8ED3C10D19F9E61EE9252E28EBB0E15802EE43083A12A0B7527088832605E3AB +pk = 09ED8CF7986F072AC7AAE4C1625501D55ECC5A297F45BAC1870B9241054AFEA54B6747FC52C4EAE48C83924323F725E31D846BAB302E149ECE9E48ED2B72039EF5B6A2E5D41EB91BFADEC5A71D8457E540B6B7E2ADB6DB049F4FC79EB8ECA0B595EE1766C65B598DCC161771A87DE059FEB67B8CF3E0EA372526136BB42293DA17B87F856FBF5788044EEA7FCA6DD6119033335F74235CFEE917CBF3471FEF20D026B3A61AC36C0F5FD4D6CE53ACDDD83134D74D2CAFD607B88FD6E630EA0588AF95FC2F9C0AEA14D765C9B2724607DDB5C700CE70A894E7A83ED2AD56CF8BCA6AF6D5B15211A70846A505B6830B23CC574AD5D5D058E9ACCD71562264086B0CDB2518C272EEE7CEBFC19463A9FD4730BD523301D057016C2DAE974FA4013EEA208D959FB6FDB4CC310A8DD8689134031A6075CF5B6BB59233DF258F1EA583AD6029D046841451EDF4A11CBA07BC4BD89AD0F21E1A9E73154FCF45704707407DDE98DCFCF712374F82ED53A694AC161E5CB0E2A77C5A1C356610 +sk = 447F6076A627BBC5AD7773FBFEB14B4BA9AC43A0F8B99FB620A7237801F470FCC2BD9FD7BEA8322859B850F7882D362947432913DD068C0109ED8CF7986F072AC7AAE4C1625501D55ECC5A297F45BAC1870B9241054AFEA54B6747FC52C4EAE48C83924323F725E31D846BAB302E149ECE9E48ED2B72039EF5B6A2E5D41EB91BFADEC5A71D8457E540B6B7E2ADB6DB049F4FC79EB8ECA0B595EE1766C65B598DCC161771A87DE059FEB67B8CF3E0EA372526136BB42293DA17B87F856FBF5788044EEA7FCA6DD6119033335F74235CFEE917CBF3471FEF20D026B3A61AC36C0F5FD4D6CE53ACDDD83134D74D2CAFD607B88FD6E630EA0588AF95FC2F9C0AEA14D765C9B2724607DDB5C700CE70A894E7A83ED2AD56CF8BCA6AF6D5B15211A70846A505B6830B23CC574AD5D5D058E9ACCD71562264086B0CDB2518C272EEE7CEBFC19463A9FD4730BD523301D057016C2DAE974FA4013EEA208D959FB6FDB4CC310A8DD8689134031A6075CF5B6BB59233DF258F1EA583AD6029D046841451EDF4A11CBA07BC4BD89AD0F21E1A9E73154FCF45704707407DDE98DCFCF712374F82ED53A694AC161E5CB0E2A77C5A1C356610 +ct = F311B8DFC2AB2EDC87116E3B8C72AF5E1867E94ECD483A0F99D256018273EC5E9ACAF8EFE5F32CB17AF6B468BC658DC242B7DDFCB74A68B2FDAB1438B7AD166F18DD33274A5188A52CBAF0CBE09E405EF3ECCF1B793671390FF2AC92A88FEC70460F4B6248B0BAA67515B8040464F5F5B6153A635FC183CFC488B5C46C30B0882DE66813913AB3FDF2EF240E2B5146F16F106A0CDB05A353039EF8A4690A4DC0FFAC9F45DF730256F6925ED6F7017F61C296E8A7BEA59BA579DBBE0739BAD26CAC05799261F8D356F605EF004CFC38BEC1DF09F0CE1BD0D0DB69D2BDF378A1531BF360E7FF8FD6A1198C5E3CA280C8D10D2364997788267C3598D81F13B80DC88494940800D222A1243CC2C8331132EB545ADBCA9A87917A75EA4099B713E1762050B29E9289448A52215B8262E8C95ECACB667DEF897C15B0A53BA13D9BB8E5EFE0F8AFCE018C72BC2F52F16FE9CB12C3237068357041B0BE6E80D62C093E79BB09819822052A6C357AB298D8F07D75221541B70129D24FE427A1C83CE876841320CC55A4D5D55AC416685A77EA90911B51 +ss = 2C2738D9C4FE9120ACD0F19D46EFC45B4C53BEACF8B213F3 + +count = 50 +seed = 027C3D5847ED4470931141104F25B19AE76117CBB64B224EE424FFB782E9A0E988839E0BDED0DF666FE8E5FCBB5DBC09 +pk = 4CD09AE99FD721431C2DA9841180EEF53A7B94196DFD3B9D6913C02C0D58FB3F17D252835A529F7A9882DBFB24F4537310EEEAE9DBEB840B88755F7677021E1BC9E09761F935C2092A83B6205FFCE669A9BD57FF58BDC987D2BCF9B96F54AE3F8C5AE422538547128ED66B7DD6BAA8B15FA4B79DA11075EBF1FDC460EF069FE87396A1FD253DBB3CDB1907895F3FC2ABDDF8374C8DAD625DCCCF8F6F928F462C9D616CEA3B354FAF1EF8F7FA474FFDC0C01A8FC9A7042B93D0C365480717BC0E5C3452C3A84C5BA711B83245A0DB7C7F5D89C71AD9E949D9E7A32DC6447499DD4B2E7BCC3B3ADDFB4671C8C3709D057246B29801019B2B34D8015D40600F5A0BFE61DD824653B44F8ADF9D7B13023B2DE7AED13045B6319FEB8465059B5C2BD4948AEBD1CCD62A8A9BDBEF60F3012DBA815D3DE6EF86061C087D015B74976D079E5CC4A72DF995846FC74974F9211BD58220FEB457813306F300E571F5BD63A5880C20BCCECCB5002400831B9404826052A5F101769EEE21BC0A +sk = 2D5DF64D62CB07FE630310BB801C658DBF3D97993E6862677B534537ADDABA4ECF14F02AB317D36CB9F0F50222CED7CF029DFF8A0D3D2F094CD09AE99FD721431C2DA9841180EEF53A7B94196DFD3B9D6913C02C0D58FB3F17D252835A529F7A9882DBFB24F4537310EEEAE9DBEB840B88755F7677021E1BC9E09761F935C2092A83B6205FFCE669A9BD57FF58BDC987D2BCF9B96F54AE3F8C5AE422538547128ED66B7DD6BAA8B15FA4B79DA11075EBF1FDC460EF069FE87396A1FD253DBB3CDB1907895F3FC2ABDDF8374C8DAD625DCCCF8F6F928F462C9D616CEA3B354FAF1EF8F7FA474FFDC0C01A8FC9A7042B93D0C365480717BC0E5C3452C3A84C5BA711B83245A0DB7C7F5D89C71AD9E949D9E7A32DC6447499DD4B2E7BCC3B3ADDFB4671C8C3709D057246B29801019B2B34D8015D40600F5A0BFE61DD824653B44F8ADF9D7B13023B2DE7AED13045B6319FEB8465059B5C2BD4948AEBD1CCD62A8A9BDBEF60F3012DBA815D3DE6EF86061C087D015B74976D079E5CC4A72DF995846FC74974F9211BD58220FEB457813306F300E571F5BD63A5880C20BCCECCB5002400831B9404826052A5F101769EEE21BC0A +ct = 8823BEC1998F9B4405A5A7357A17CF09645E956D0D24D0393D9114BE9EAD88007C56C329EB811C38DC7D8735A4AF0BC56BA8785D6A5A6DC6181B92D6EF0D250B1F28D4CEC66E0E4C52860476C081D985C4A076A5FED8E7D7F810EC9A99C6C5B783C24F44E2C71404024A9E7C209DC02AABA1F2209A4A6E604AE4C88CA5045E73BD7DB671F27283AE1FB505DF2B845646EBF4E7D2E976B4E8C265322164CF8969632F283ABDD3B888900F4E31F3840A2F168F180940B919B0D31208AB28819A677B5FAE3F1C400BBFFFA305BD9DE2CB90265DAF3802E31817877D48DDCA22F61EAFEE09F9F7CD90F14CAD53E6FA0799E9495265B171902130246CCF0E78C7AA39D209DF3A1249111E89275E6408F2C7C9B9F153487B568CB24B1AD7F4CE26D97FE7F23B08BE797E1BE9A9451D1116C13D03B3CAFDC6A2A2C3D23A3E73F47369418927A06675A6B91368DFB07AEDCE6666B39A430CB48258FC381232B0244B09C27479EFFFDA5F1026C3B271215286EA6A189EE4BEA54942ED5C3D506A4E5865074B0130B39F640AEDB4E0493A8B6477A60B7A +ss = 38046EE145F00DA177F6C1EE6EB51FDFCE21F360B25C2FDF + +count = 51 +seed = 450751D4401737459C6D93E6C5F2FBCC4A3AF7CD7250CCF404BBB817A67BAB7B4C9D0EF4570BFE25CF919DA331C31D88 +pk = 4887A93D8B7920507AEE3CB0A9EA506D90151DBC44C8EF699A6B0079BF497A34A3A475F54BD7C991F210FC0FC14B582E59BC44473D27A16F592EF12FC1AB02AC99E6FDABC966EA95C7F7FEDDAC29CC9252FA1B45831EE846A7373A3B69E6701178C1B6C3B21A41B352CC8AF1F782D1C4B33997B1999460C290E9347EDF342DE6C2CE7B7835A563BB6A01B0A3DAE0AC9BFCD87C15EC76B8EDB5AB149938D666B8132ECD0805298DFD4A36FF83F6003BDB502866789142125291318DF51A3A9864460293776122A0AA49A263CE64E5F859316786E9842F0BB982DB273A1E09015C3250D22EA7AE178FA8B412AA4CEAAC7BEE294CA6031877951A08991215E5E79659FE4CF43342785A8B5E322D585E51EC5B1C427BAD342A338B8FADD350D2C762BBBCD959C4E5EA1CC4890776F4363CFDBE202E9A4A357F0024A50DA80EA1B3648554E926FD49BC8CDB0298E9562ACBFADD69C97BE59DB9FD8CCFEF400FB3CABF8055D2EE43A406B4C109BBEDB72AD408BAC01D1765222FF16704 +sk = 25056D1B8113BB362DD979D98643D7A7AC9C4F95994C0BA0F48A9254DD40B117941FA35A66BB50296327B725525DEEF70E128CA8045EC4014887A93D8B7920507AEE3CB0A9EA506D90151DBC44C8EF699A6B0079BF497A34A3A475F54BD7C991F210FC0FC14B582E59BC44473D27A16F592EF12FC1AB02AC99E6FDABC966EA95C7F7FEDDAC29CC9252FA1B45831EE846A7373A3B69E6701178C1B6C3B21A41B352CC8AF1F782D1C4B33997B1999460C290E9347EDF342DE6C2CE7B7835A563BB6A01B0A3DAE0AC9BFCD87C15EC76B8EDB5AB149938D666B8132ECD0805298DFD4A36FF83F6003BDB502866789142125291318DF51A3A9864460293776122A0AA49A263CE64E5F859316786E9842F0BB982DB273A1E09015C3250D22EA7AE178FA8B412AA4CEAAC7BEE294CA6031877951A08991215E5E79659FE4CF43342785A8B5E322D585E51EC5B1C427BAD342A338B8FADD350D2C762BBBCD959C4E5EA1CC4890776F4363CFDBE202E9A4A357F0024A50DA80EA1B3648554E926FD49BC8CDB0298E9562ACBFADD69C97BE59DB9FD8CCFEF400FB3CABF8055D2EE43A406B4C109BBEDB72AD408BAC01D1765222FF16704 +ct = CE919850F0EF51FB5A89EEEE3188B2B3E8E3F696982CA8C310D4B8FF14FC051F5FD72D614B941C41857A1BADB0C8E6C755492C15829239DBBA065F288B1F1517074693623E683D121022318EA61358F77609811CCC66719D4C2AD729AECBC224BEACEF3037E21A0D80FFA5CF68105462E99B3EFDB4259E64A47D4DE38F3B66BDCBC3F2FB01C9C84CE9CD1739BB12AA064F919E05D3A41630339C38F201FDBA890DDD78F64DE5B931850EDDF528129E88A03AE681D7B7B41C8BB7B2CB1355E792E971A27F5D94E6AAF4CD10B50AA4EC364E249378AC9DA0A8B4D6B7B48B74ADB756A3F102A4B062C7F9888760ABFDC0AFD21121038C4BE41AA742F106791EC116E11338C183F77FA10AD047D603F755E20852D8B5975BC124BF1AC563C2D38D0EABF7A09FD19540E70F6F2FB4CD74D82ED3A77F8C20CEB1E177ED3794D42209F4DA2F420164B60D28A7390A91FE0755696BFE3A97A94F6FC89483ABEA27E1AC7F21C26C76621FCE814522DC90BE83D1E3B59EBC89B9EB0D1DC12E533BBB051BC013BC4543BC4A9863E763B0C89E5AEE77CDC9 +ss = 4A6C24DB6F372A28188D43BDFE07416177EA68E265CE3482 + +count = 52 +seed = 5DE720F2D152BF4E1F96A61E7AE5F1BED6B8548E32638C2CCEC9F43B87D1BB43DFCF334F0582984D27E440D519AB662F +pk = F7BDE421E0571F51812C42AF7712D9E17C73CAAF9980CC8372E7D59A1F7DE392568EBDBDB1AE716B6A57199A76DD9924478006769536158A77098C93F39E1059017A18D98102B622B3660C6FDD04812F5C6B5B80420C4D8D4C6F3A1F646D293A725BF068DB5DC50FFD038D5A73F97644FB1BCBCABDAFAE4B52E329DEB229577C62FEB62E4DA5FE1533CCB45B58595F87ECF8237B92B1DCDC89CD788A0B32981A1FD306F8303DA07F88DCF0498A12F2E449E56451D06BFF570129CF5E0B50854B2F3E733B2844D60A86E8179A89D7694B8FC346BB0882DA6123BF3304234AF7AD14BE737C526F6B3E1C24904665040B05F03AE07D6A8ED5BBA499A70260F7034084010DF834DEFCF2F714EBF2C95DE06FC93B4F90378096C15ECAB822FF408148D243C743512BA6579747527A97D5AC0A5F94C83D14699FC674383DFD0D6220A1339BDE8A3264874A513AB84A9AF109E6CBFFD4C174CF2541C97C1BE910F0DE62A7FCB9BCAF55EF2DBCC4B7C30ECAD2CA1295F7530C8E05BE6023 +sk = E4D34E12982AEEB1D62FD488D9B9E28557ED3429292239FBE6C45C7FC62329B13C8D29844405DB8FF6860DE474BF727ECD19E54E6E1A140BF7BDE421E0571F51812C42AF7712D9E17C73CAAF9980CC8372E7D59A1F7DE392568EBDBDB1AE716B6A57199A76DD9924478006769536158A77098C93F39E1059017A18D98102B622B3660C6FDD04812F5C6B5B80420C4D8D4C6F3A1F646D293A725BF068DB5DC50FFD038D5A73F97644FB1BCBCABDAFAE4B52E329DEB229577C62FEB62E4DA5FE1533CCB45B58595F87ECF8237B92B1DCDC89CD788A0B32981A1FD306F8303DA07F88DCF0498A12F2E449E56451D06BFF570129CF5E0B50854B2F3E733B2844D60A86E8179A89D7694B8FC346BB0882DA6123BF3304234AF7AD14BE737C526F6B3E1C24904665040B05F03AE07D6A8ED5BBA499A70260F7034084010DF834DEFCF2F714EBF2C95DE06FC93B4F90378096C15ECAB822FF408148D243C743512BA6579747527A97D5AC0A5F94C83D14699FC674383DFD0D6220A1339BDE8A3264874A513AB84A9AF109E6CBFFD4C174CF2541C97C1BE910F0DE62A7FCB9BCAF55EF2DBCC4B7C30ECAD2CA1295F7530C8E05BE6023 +ct = 55F3EAAB473FEBF0CAA4B5C5EB737BBFEC56D4E1CB64899E1FC60BD392ECAA345D84D73F1896527F79E966F5EA58C683B43386AEE0B98CF745365DFC0F2525BC5E692947E7257585DD766E6BC9FE0104F8FCC402F947AE491437A797FC7BCCF6BA7447ABB15A0DBD80E11E419C617B2DFDD231A2C39ACF734BB9D2713D17975C78F8255F7CE70BE77ACF8B364A29600A419542A74DF74F037824CB73BF62070BB7D9AE6967D0F4363544312006F0C9A26C3ABD7B421C8B481F47B2A01FC04DACC9915CD373F4CF9A823A5E3B0D8125E4D8F2576536739D5348EA9E30E03C5F3B9B115B9B36DDCE3AA2C8EEAAC1743000041C0CE97F4F9A630726B713F72339E81E36C0EAE60434DE616CC0E2738B6090CCE6EC0D1F3C7F9E95D66BBEB87218F9580A236824C292FA312AE85C9F67A5C45393781870B5C08F6F5209C2DE8B1DF17E8309CA1C0E0DBC981F2FC3911F054497F9E507A5E9708C3F964E16678D943425162892D882C5D7E8B218EB69FA71CD4F61FE7EE8EB5A8F512815829B4A6BBE3D27AA1E48F570EED41B68EAE8E2FDD03499 +ss = 6611465188E82C488DAA81274C8E37E2B3C93A885D9009A7 + +count = 53 +seed = D71729DCBB27D7CB39E9E905025D3E55C8602EFBCC483C9B866EBF82326157833169243C14550AD728BD1470F39C642E +pk = 7502D2E942D8007A43FB1D68F927CC790183428356D5C634CE2FFEBA44D65AEAE01042112EE533558BBAD88D9498F2A563239C4ACF001F80A68DB797937C14FE8797EA33EA459BB18857B3EA94F0649DB53C5E2DE2B6F23C19A4640036780761F440632231E4D1D3B0441133A943F5D019CE5745EE65B96277B7D91E7D12D7F55BDD61556EB950D97C42CDC0F3203E772D32970BF5CA27E5CEC558A66158D450DE776D0077AF60944C0C52A2385FE7B617E2D75977E5C1948DEB780A20884B8BC1BF9A8CB1BC3626246DA132924466315BCE12B7B20369F321303A73B55EC1CF78C0B575D6D9E31254A2319FB38EDA515B267986C8133A81C0629F37A6BD6398E02890062A2312E23BD5A52DAE989CA4DB261CF5430EFD440A31C8F225B052DE568D25EE504B368FE4156F14B7041DE998D59D01277FB29B5A042CFF84127B9E8C104331A89276A1E7ECD4AF21EB237D5494F2DA6C088C486717506C3D54B58ABA5D149CA64459D12E148188212D6A6EA595ECF587517D32FB0D +sk = CD6A99396EB3539CA663A51E42063A3A262CC1C5A5FCE1565A3407F591791A5DB4578B5972093A95BEC3B8E70C1D542C9B5C9789729F89027502D2E942D8007A43FB1D68F927CC790183428356D5C634CE2FFEBA44D65AEAE01042112EE533558BBAD88D9498F2A563239C4ACF001F80A68DB797937C14FE8797EA33EA459BB18857B3EA94F0649DB53C5E2DE2B6F23C19A4640036780761F440632231E4D1D3B0441133A943F5D019CE5745EE65B96277B7D91E7D12D7F55BDD61556EB950D97C42CDC0F3203E772D32970BF5CA27E5CEC558A66158D450DE776D0077AF60944C0C52A2385FE7B617E2D75977E5C1948DEB780A20884B8BC1BF9A8CB1BC3626246DA132924466315BCE12B7B20369F321303A73B55EC1CF78C0B575D6D9E31254A2319FB38EDA515B267986C8133A81C0629F37A6BD6398E02890062A2312E23BD5A52DAE989CA4DB261CF5430EFD440A31C8F225B052DE568D25EE504B368FE4156F14B7041DE998D59D01277FB29B5A042CFF84127B9E8C104331A89276A1E7ECD4AF21EB237D5494F2DA6C088C486717506C3D54B58ABA5D149CA64459D12E148188212D6A6EA595ECF587517D32FB0D +ct = 40650D6491686A9501CE92B7847D910B2590FED52A4B4DADFD286BB8E88714E7D8324C7169BE8BA591A15D6C65610B784589A46E69A5A20565FDDE9B49941C05C17D040ECC38020CC574F83EF9D8B94EBC42CFA36991EB3955081EFF82D6A398F2B67D84F87B71D51939074B1A7E7562A53CDF71F427BF536E92D26C610A2FCEC7E861C33EA1D5069C136CA9EB2855C5451158A60E02A8B35F0C3BB45A4214E9167EA81CFE6FADCA48A1EDE89AECEA213B6A312E21E6E2A8D981148B3E4A7CD7FA6F9BF9857B96DCA7EB2A48638DE84BAB37646D9F90DF16CC82AC9D873D00FE36B9213ABCC19BB6AE8533AB4903D99B768FA42B89C79A6B66DA8D06D4116CDFB2AC643560023C0234D4296C9D5BD1A6E4C6994C900EEE0A136F0E19919857D8F7CF6AD147DDDD436B7998D4617A1B58D3FBC5BE78DEC37A722D07519A1ED6995C45AF687619BD0D00E1D20E6EC9EC83CF6319CA30564974143E0AAED1B8DF4A4970AC33CE3B0738AC522078BDCE647804A10C6DF5BD1BB276004745252BB9270F325196904B9F71F7A84E5E447E78F54BA5 +ss = 3F068357967BF2EA7A4C4A1C3A7DCDEAB3690623416DDAA9 + +count = 54 +seed = A7C2C8EDB3601396BEB2DF0657EC82FD5780A2723581A9E03DEE1CDB018440439BB1142CAB0487C5D136E9AF46338AB7 +pk = 1EE61186295EA122629A9A13F24788AE62FC843C7DF83F0C42C3899957933C1E1A7C028F9239C49D9D4712B802F7FB0D8C9042328F82B632C2FD7F5F414236B9E156CD691EB74A3F48C2BA25EBFC533A244D42AA7E6EDAA5358F3F77F46232FA0C2AD5885788D558C45A01D49AE0AAEA23CDF109BE0282D1D9F5872B183B5C889D38978A4464E0D78D564C6153D8154A6151027254E456CFE72C545929D95998FB235EE178F678CBF00AB7A4930FC2C5F578ECCA25D42E7743B2FAF932E58F785A45CF7CD14B4FCF648A51D208C7FB4474520446BFE2AB7BCAB31180CB62F1A66C5667FBDEFD27FA4A87BB4ED04B3661AD76D1CE7E683B71A60A1615B4C4C022E9CE841B48D6D5A71C7873F73248AD0686001F2A55C4ACEBA6CD1ACBE1E32745C022FEF67CF009A3F437A8C6A0C184724AD7C38BE38C52EE270C3C7833E448F3870EF987EFEFF032F94D83B6620B5ACA4358B338FF89583CDF4479D3972E993D307FBA4BF8DCBB2814704997F87AB0E0FBB2BD619AF803832513 +sk = 6C8C53ED6F65E6B2E324B84364E10DE42D1C26A106D4D1C9B9402BF02481CE4B27A52E87FEB92C4399C7F2988D40E942E7496AD15AD2AA081EE61186295EA122629A9A13F24788AE62FC843C7DF83F0C42C3899957933C1E1A7C028F9239C49D9D4712B802F7FB0D8C9042328F82B632C2FD7F5F414236B9E156CD691EB74A3F48C2BA25EBFC533A244D42AA7E6EDAA5358F3F77F46232FA0C2AD5885788D558C45A01D49AE0AAEA23CDF109BE0282D1D9F5872B183B5C889D38978A4464E0D78D564C6153D8154A6151027254E456CFE72C545929D95998FB235EE178F678CBF00AB7A4930FC2C5F578ECCA25D42E7743B2FAF932E58F785A45CF7CD14B4FCF648A51D208C7FB4474520446BFE2AB7BCAB31180CB62F1A66C5667FBDEFD27FA4A87BB4ED04B3661AD76D1CE7E683B71A60A1615B4C4C022E9CE841B48D6D5A71C7873F73248AD0686001F2A55C4ACEBA6CD1ACBE1E32745C022FEF67CF009A3F437A8C6A0C184724AD7C38BE38C52EE270C3C7833E448F3870EF987EFEFF032F94D83B6620B5ACA4358B338FF89583CDF4479D3972E993D307FBA4BF8DCBB2814704997F87AB0E0FBB2BD619AF803832513 +ct = 5A229B3C3524E57838F0079074FC2D9D527890DFCBC6E5F83DB85CF3752B67F30E363EEBBC4DCDB0536FAC2D240BE47426D0D4779AAE1305664DBF4A57110A664F8B2B49EEB39974294E455099EC98E5E972240AB6521075B05ED8AF8B0BDB1AF92353F353EDBDDAF04996B6CC83D3E89B2855981EB895EA04F11DC3870CE71AA30076AA72EA9EBB686E4E2E45F489E67C9CB6CF22B1D8BEF243F97E41ADF7CAB8293FD2E950E1F9B3014531B8E4F8DDFD74B7688D03502C32B12CA317518E28A30A713CEA817C32101906D0EAC55DD243642E47606B63885F1CE6E1EF76AA7FCFDB11376E4ACC386A1FF95CE8454481081431AD785CA58C013709172DB03666EBA3F858C750E33067290AAFEE066A1F9B24EFFB14DCD26BFB9D86F6217D217E8C7A5951A2EAAF963D3824E9C44285CA799A4DCFFD9CBA1920A016FBD40E1449E6EF636D91421465A2F3A15ED829D1BE2DC988FDB8F8E92CCCD5BAF6C93084E2BE6F361DA62D63E7D942A4FDFCFD4F8B978714E310565F1C99115F71C71CE99642BAC7DEF32438E45F65BD4E7B1D32E92750 +ss = DE7DC467814DC94405A38C45B0E6FA2984DCC97598D75874 + +count = 55 +seed = 467F6158CB86B724039FF18C47950AE5C49170163C910FC9A9B30141F86E9C06EBCEC91497BCD156D95758C9F0C6EF91 +pk = 05C4F72C66A3173A2DEF37EA9BB834354BCB234581B5F5E145EFEE238B70C4D99FC4CD811ACF6A1483DD309E87E8E4EFAD10710E1387644BBB5BA2561ED623D4D406A687C08D4AB86E5510BAF22D07112660DABE21A5F6E6ADD4912A7ED8B79738D6CF50EC88CA9526F9F2B6C299F1DB78B8C468D2A61BD138A8A4DF8A139289CC727246EA0C401AA475AFF9836740B242A7DC93163ECD9823C8B92F615B288DC8BBF65BEBFC56318E73C9F8BD8FBFC93E45624017BE7A00B118BEBE023C3D7738D3D85EFE1872CF80F91E568BD389429E2B0CABAD37E8DFEE15047DC8A715A584AE71849C3A4AC31158DC1650266A518492DF3AE351963A9CE0041A078C9BBFA43CA6BB3368FE835E14FF12949FBBF902AAFEE0965EE6BA974F0DFC69AF75D2751B73AB50F99FCF85113AEAEC13DC8A7276002EB58BB3AD686D2C95F12B385AC69B4E36D25DBA0347EF9258BBE242CDECEE07CD90C70DA077B9F1CEB5A2FCB2DB8BE77CF9D6021D13FF4CF2460AF6B486809080D9968B69AB08 +sk = 2107204CD995F1DF14314D5381F8C5440F09A347502E161C24C3DA70FE850E80AA818301D60C70F3038153866DCD5D179E22DB59B8991B0405C4F72C66A3173A2DEF37EA9BB834354BCB234581B5F5E145EFEE238B70C4D99FC4CD811ACF6A1483DD309E87E8E4EFAD10710E1387644BBB5BA2561ED623D4D406A687C08D4AB86E5510BAF22D07112660DABE21A5F6E6ADD4912A7ED8B79738D6CF50EC88CA9526F9F2B6C299F1DB78B8C468D2A61BD138A8A4DF8A139289CC727246EA0C401AA475AFF9836740B242A7DC93163ECD9823C8B92F615B288DC8BBF65BEBFC56318E73C9F8BD8FBFC93E45624017BE7A00B118BEBE023C3D7738D3D85EFE1872CF80F91E568BD389429E2B0CABAD37E8DFEE15047DC8A715A584AE71849C3A4AC31158DC1650266A518492DF3AE351963A9CE0041A078C9BBFA43CA6BB3368FE835E14FF12949FBBF902AAFEE0965EE6BA974F0DFC69AF75D2751B73AB50F99FCF85113AEAEC13DC8A7276002EB58BB3AD686D2C95F12B385AC69B4E36D25DBA0347EF9258BBE242CDECEE07CD90C70DA077B9F1CEB5A2FCB2DB8BE77CF9D6021D13FF4CF2460AF6B486809080D9968B69AB08 +ct = 83E19BBDCCBC39BAE4D61E3FFE4688EE5E2D69C0589F49D976089315753DE7D7B494D9513CA2DEC922DEB8914B8E85984790FB995D234189554F598E3B531C8A09EDFE8B72554B0D4CB3C06C212CFF0340FE476E1B34100DFE9B0CF896DB0D4184E981329656AA727D55605778A32BBB017F4DD31C6A83DE3ACE8B711F323217F3081E76B644D8911FA35207EF01B265307DBC38727D7CCFC9D8430C4631CC26E87E82CF1ED1127A7174557A6DA950B353AB89587E3421705A96BABA2F320A66613DE4BCCFFD927967456BD726DBAA22138D4F0A5DFCDEBC46DED8BF54508B20670AB83C37BA1DF7070051C5CCBA3F9498E3B6152D30AC1EFF825733D4C1F29746F821A4EDFD24D3151FB43BF22C2B05CE3463A5EF04A45C398FAACBA206B19189971BF0D68F52770C0A5B3D9EB218C60344D9DA55ABB193088409F587D9BA003BA7EF225B215BD4D0EF14B5F8DD8422FD6E0042E8C7119BD6D5D59A568104936546056740EE09A46D2AA2E27E1E2FA787975430243CAD6F5E38ED96B31D40D0F4193EAF3359360F2F56A0E94D62E00DBC92 +ss = EABE408DD38AB61A83E0E1515ED453208B6C687EFD749C02 + +count = 56 +seed = 687C02DE1041ABAC7B2C1E6EC2A7C3375552ED5EDB10E3A8139C24CC76BDA44D719D8121A81D47A0B762B4E9EEB85235 +pk = 2D7EA08921DAA4C52AAD77E37C5C02F633DEEBBF793184C5DA9DF45CBE5F5DA56D8F4D7E61E517DFF0FF4C2849ED0B2D2B83570EC8935D2083760553A7A134EDBC01B44731B3032A700300DCD25CF8443B39EE22F0DC960C409886151D2C777082EC9E342D373912684AC5F98BE3CABD509CA7141DCB6F24D67A428C9C39AE86EE7BEECA86D70EC57DD67789B998E5239A6A1C624DDC6991B05BF9F70A0070913B9B0D64AE60AC20B598B18C1476CD22FD1474473E277EF6743DE4E6018C4E306D24CCA8895E1F2459305BDE9D466BF54F5234E1491166D58DD1BA56962BD6C0BD6632EB9799BD7FD6C7F01FD835C14ACD4532597FF500B4C14A7E1AAE3F0748E27AEF6789E93A42AD10E57DE310BE2F7D5DFA4FD8F0D9DA4A3ABABCBF674999A1126CEC08C22272AFD0C6A46BE8A0F738609B7633F37CC9F2A0166051CA343351FD244469E15C882A454D91BEF6ED3C88D26CBFD0AB003C97E7C9A9E53C259127FEB5336564135F14F519C90D4A5ED283B9F9D248A24254331E +sk = 63A925685A8AC5BBD918FAA33AC397D1FFBCF99135D9DA7C3AFDB8A246A56EE71465591831C371F2EB87467B0559DEDD776BA063EE6D2F032D7EA08921DAA4C52AAD77E37C5C02F633DEEBBF793184C5DA9DF45CBE5F5DA56D8F4D7E61E517DFF0FF4C2849ED0B2D2B83570EC8935D2083760553A7A134EDBC01B44731B3032A700300DCD25CF8443B39EE22F0DC960C409886151D2C777082EC9E342D373912684AC5F98BE3CABD509CA7141DCB6F24D67A428C9C39AE86EE7BEECA86D70EC57DD67789B998E5239A6A1C624DDC6991B05BF9F70A0070913B9B0D64AE60AC20B598B18C1476CD22FD1474473E277EF6743DE4E6018C4E306D24CCA8895E1F2459305BDE9D466BF54F5234E1491166D58DD1BA56962BD6C0BD6632EB9799BD7FD6C7F01FD835C14ACD4532597FF500B4C14A7E1AAE3F0748E27AEF6789E93A42AD10E57DE310BE2F7D5DFA4FD8F0D9DA4A3ABABCBF674999A1126CEC08C22272AFD0C6A46BE8A0F738609B7633F37CC9F2A0166051CA343351FD244469E15C882A454D91BEF6ED3C88D26CBFD0AB003C97E7C9A9E53C259127FEB5336564135F14F519C90D4A5ED283B9F9D248A24254331E +ct = 7D07124335949EFB5EF3FE6101C6F57C0003A2224DA08D9278981B04CC4D020983A1EFE285B2ED923AE520D930A63999950B67F8FFED5D5F4CA5506726BC202196DCC9FEEED4A8337D94F310F2D2FAB61C940F8718C163DEA1EAC752B54B359558031B8D04F1DA3271863399B9A2BAB73D8280145B13D74C2E1EA709A93C39B47C89BC6A60A6E00B52242630B7D761CFB63F63333A0313A3749E59A59CE1AC401AA578DC2DD6714654E95F2ED7F58995149871E66C14EB59BB564478247A3B27BFE9765EE98A6E1BE199235562D2FB398650C0534E06CEBE692439D729C5B5E98BEF341D25DE6DB03A49135B2D0DFE38FF595541C853249BFD1F200B48753148EC2AD5EBDE458D420E51CAE86AABB8FD8C46B9E3D71C8C1F3AEC2333C0FC70D1B6B4E5A8AD647254492409D7254E53A6DB2080151183CBA0DB161BE64F9A0BECB6E66FD7EF1798F592C1E06965A36349954E0B882EE98BE5206E6C894D660F1F7BB0526AA3100D354A815C080922D1D82359B7A1F1E998D8D512074EEFCCE28F5A220072A588F448DD2AEB3396B3A0FE9406 +ss = 3CC2D29433CE0F0B2CED2B8EEC0000798EEE8C0B93D2D1A7 + +count = 57 +seed = 4142237070C216BCBE245A39BD9220533C97651D84832B26727855AD994A0760C52B9319AD404693E4248B8C5FF324B3 +pk = 247344A11D63CADB095BFA6F6B88D8042AA0F5C99CAC728EDCBE57D9F43087A7E8B0B495E5D274366E57E7E4511BF1558678F265836012479B686AC5D12D106BBF84DD13539E4B29A9F9232B1C25B80961537A17537E5556B8DA02F004CB11B584503141A9C253ED5CF350777FEF37429F1A3E0F505A8FC0ACE0832F4C189063A5B6DAA4350BEFBA31803D8CEBC6FC78090CB08581787FA8C59FA127079084DE83030661EF6DF1753151BFE2250418C834CD17CB15EBA947323807983440C68747FCED74B2BFEB306E972347339698315EEBDE4695CBC39FC92F9BF491FBCDAB166CAF93AB4B8E78FFB943B8A4B45FDB36E601BBC0DFFE01472D2A345BC5CD8FC98475ADF52BF53584672098A09D5AA43E7A254448991A2597BAB9B366413F4507E093C0CFC2003F721E74703DCBE0074152FFC7A2588D3A1B0A2952E1A38727F93CC2B88FA25A4F31C836D0667728F2396DB6D45189E13425D323C92A3CD62D433C4AD898F8244F0C8075F7F99E73D1CF3AD12A4618D61AA000 +sk = 6A1AEE5E708C1B47F02BDACCE4F56C860F74FC7CFEC1EF3B230E05B7114FF0395CC6634DB1EAE8258072D09C09F291E92D6620B177DC5007247344A11D63CADB095BFA6F6B88D8042AA0F5C99CAC728EDCBE57D9F43087A7E8B0B495E5D274366E57E7E4511BF1558678F265836012479B686AC5D12D106BBF84DD13539E4B29A9F9232B1C25B80961537A17537E5556B8DA02F004CB11B584503141A9C253ED5CF350777FEF37429F1A3E0F505A8FC0ACE0832F4C189063A5B6DAA4350BEFBA31803D8CEBC6FC78090CB08581787FA8C59FA127079084DE83030661EF6DF1753151BFE2250418C834CD17CB15EBA947323807983440C68747FCED74B2BFEB306E972347339698315EEBDE4695CBC39FC92F9BF491FBCDAB166CAF93AB4B8E78FFB943B8A4B45FDB36E601BBC0DFFE01472D2A345BC5CD8FC98475ADF52BF53584672098A09D5AA43E7A254448991A2597BAB9B366413F4507E093C0CFC2003F721E74703DCBE0074152FFC7A2588D3A1B0A2952E1A38727F93CC2B88FA25A4F31C836D0667728F2396DB6D45189E13425D323C92A3CD62D433C4AD898F8244F0C8075F7F99E73D1CF3AD12A4618D61AA000 +ct = 6C1CFA35A295B889CD2B8AB7FDD37BA2939DBA381C3F5F69648E65A3BA44B218A50290DF66614255C0A2B0C2B3F6756BC2599226AB4DF1B5EFA05AF4538B3E0909410CAD2095A8561F37A3FF5ED594163D1518E02C98DFCD01267D6EAC8349126F558D72BBB2705B2F8717A28C0B92EC3DF996BEF59C22C621DAE20E411FF92081BB06C5823C975A241020E0316946E5A2729932CB8C4D0CA822D5A08933735AA45783E674285406C75A55A5B47CE99B0C8E86EE937E8B9B67508B7C3C3CFC53B4456CA4F2717A8BB27A632EFC2E5700305E1021C8F9ED7594E1E938DD9877B11A6FBB84BF4FE0F8DD509B61DF4E49F99F067E65C1A7D93F9F48762C1F480B992B7C1D87A63D3301C99E8412F26EBE722F51C47FD3865BFAF5F5D5C930C89BB7C0455075E15F3E1B75DA8EA734388BE486DBF8B3706B45162EB235D1BEA4C0E466D6D9A56FC6C79176D037B5A05E926A8CE23713462B2F9A87344DA0F93AE80569458341D32082D0ADEA146886BABE5705B5278BC86BB03F0B03167FF23644B344490B513AB6ACDC72417A556171B6178C52 +ss = 15ADDD6F14BF3F56D5EC1747A00A4BDEB6E01EB242D939FD + +count = 58 +seed = BD334D7B7EB14E00E68863F2E5551A095F8AF10681C28353FD19B9A7E70B8BFE266840860609008A567ABC66316C77CE +pk = 9FC6442A616B1E9D4D14E604BAF066077048ABBB5583A1E9EF84727315E944318B79EF9BFE9C5803E35580866946456AB855F3ACD00E0EB99C8F8E52033D1CAED972AF9C1E9E2ABB5699E34D768514F8241B2428D1BD76A319F618EA0FD003FD07DCA0CAAA7DDDC0A7AA6342DC2CA49D4C95716146A70EF34062A558FE361F26DA6F30E917BD732D7BD27CA3579675F5F67094F78224A83824765D051501B287113E6E2866762BA3BBF209D53B629453C4C2BCBDF80A9C4C3963801601582512C9CD490FE880AE6C2CC2092C6C6C749BD263390FFD294DA90094934D39534976947B52CF4709B6AA64AB7DF874B8C451B6A706FF6B1FCF13F8DE613CE036B1D897756E84E4E80961AE4845A3A6029405A08D93C8BA71D015CB64CC97D4DBF93D858F27E054488F3702E00E9329D91DD0BFFC38B9B95466B678932E6BA9D7A940E66FD8C43C54CA9FCBEB2BF72FEA887A4A949A282B103D556CC63CC737CC9FC1ED82B9E686E6633472EB16FBA5A282D3945B6A246490B312A819 +sk = 6396B328B100E4C7F4BCAE69875EDEA1A1982421558C608C1100CED48ADD211A5C937B8D6079D8E271AF3F949EDC61F70E60453AEF20DE099FC6442A616B1E9D4D14E604BAF066077048ABBB5583A1E9EF84727315E944318B79EF9BFE9C5803E35580866946456AB855F3ACD00E0EB99C8F8E52033D1CAED972AF9C1E9E2ABB5699E34D768514F8241B2428D1BD76A319F618EA0FD003FD07DCA0CAAA7DDDC0A7AA6342DC2CA49D4C95716146A70EF34062A558FE361F26DA6F30E917BD732D7BD27CA3579675F5F67094F78224A83824765D051501B287113E6E2866762BA3BBF209D53B629453C4C2BCBDF80A9C4C3963801601582512C9CD490FE880AE6C2CC2092C6C6C749BD263390FFD294DA90094934D39534976947B52CF4709B6AA64AB7DF874B8C451B6A706FF6B1FCF13F8DE613CE036B1D897756E84E4E80961AE4845A3A6029405A08D93C8BA71D015CB64CC97D4DBF93D858F27E054488F3702E00E9329D91DD0BFFC38B9B95466B678932E6BA9D7A940E66FD8C43C54CA9FCBEB2BF72FEA887A4A949A282B103D556CC63CC737CC9FC1ED82B9E686E6633472EB16FBA5A282D3945B6A246490B312A819 +ct = 5ECE6B89BDC8CA7843493040B9E31E0C7DAC41A23EAF2B4317DE9A444F10DF86C877A29C6BD6AB3898634E37FA391CBFFC356D4C304589FAA564E2962351086C214E5FBCE1D809E961BC8D7138056F1F2A01F8C2EC246C2624A1997700E8CF65DBC3ABDF79B6ACFA6F8435564FBE3C04A06F9FBE1587726235610EE1A8153C816D40AFA0510F157267FC6003FF44C653F197C7D1EF8315564A82898AA3F6775AF68B2D352B1E28F79E4317B3E8E4EC83AAF9DEBAA1BA424EDB4DE2DF0178352E01567560DC54762C07F1E5DF732764EF6741A64DEE31D04FCF74E5DF9F23CAB1C7823D49588BBB77C9D70A61F0A0D771A778695DE565110C6BD7AF26DE441304FE78827284D3C635C17E9655E1E3B034C1B072BE0AAF78F3513772CC320684A80BF0D78EF8FC2887F4D42D28265EE611EF15E8F027F1C618393428102DC14DA76C6308BCFC087592181EB8256388FBBDEEEA6B91F69A991E3EE88DA515EC561F70F75FA5342A969C272724DFC376888AEBCED23AE910DD9E271F7805D8C9024CBD6E1014E0B9EEBCC1F8146AA8F21799C15E +ss = 609CE20AA0876C387C66550A52B0EED700B56BE5D4E1B5AE + +count = 59 +seed = A0264C58AB1F2CBCB212077FD378D340307ACCB31F1312137CF84E3D3135044D4EAE8BD38BC3E540A0C14D46458F6179 +pk = 0C84F64BD6A8A8981A7BB846BB66329B8323795CB2ECB58CA242FA6391A38AC78D5C2F2355207F4A37211976CE2C552D21DD5B2F35ADCD2ECB502AC85A4B3350E076F843DBFD5126238175AAF041FA98BE3F4E3D86656DE9348C4B0DD0352F2C49BC0EB71ED650B809DD428CCBDAF30F4E9D3D3627F5B30C124313F1B33B6764CBD00B8A90FBF9F5DC737768FE25A570602A02AADC057009C487B53ED07D8DCCDD4148BB9FA1619BB0C93777FCDA3CD25B9F0D8CC1D0C34F04D3E1FD032D1B6918686D0C3A647C348DADF60CFFA0DB45CC3F0F70C7FD810745189599ACFFF9BDA5A865E108556F11F4C34B9ADE1C716BBE2661B859D52F333EDE1D272857725BB22B35C0F95391818FB461E510979C6E72300F86B595415D940DA0E57C9873489F67F38FE7ABD9C8D4945CD71E96325F43F154F275CCF1A58CC22E758251018F64D2151C0C844C607E3230DC1A6345FFA2909C19E5A05E5747B89BA400E5D8750711AEEAA37B25C9C19706C96422AE32E3C2C42BBB4ED1ABB32B +sk = A453BCACDD2B0D4646009E5ED451C3C45F08FB827EF733DB7A3CC8AA3239D4C52CE4C95AFDEFF6EFBFACAC10D294EDC0E7CF4535059BFD0A0C84F64BD6A8A8981A7BB846BB66329B8323795CB2ECB58CA242FA6391A38AC78D5C2F2355207F4A37211976CE2C552D21DD5B2F35ADCD2ECB502AC85A4B3350E076F843DBFD5126238175AAF041FA98BE3F4E3D86656DE9348C4B0DD0352F2C49BC0EB71ED650B809DD428CCBDAF30F4E9D3D3627F5B30C124313F1B33B6764CBD00B8A90FBF9F5DC737768FE25A570602A02AADC057009C487B53ED07D8DCCDD4148BB9FA1619BB0C93777FCDA3CD25B9F0D8CC1D0C34F04D3E1FD032D1B6918686D0C3A647C348DADF60CFFA0DB45CC3F0F70C7FD810745189599ACFFF9BDA5A865E108556F11F4C34B9ADE1C716BBE2661B859D52F333EDE1D272857725BB22B35C0F95391818FB461E510979C6E72300F86B595415D940DA0E57C9873489F67F38FE7ABD9C8D4945CD71E96325F43F154F275CCF1A58CC22E758251018F64D2151C0C844C607E3230DC1A6345FFA2909C19E5A05E5747B89BA400E5D8750711AEEAA37B25C9C19706C96422AE32E3C2C42BBB4ED1ABB32B +ct = 09147DED4B9C4DE5ECCF4A7DDD855656320D2CA5FCB74C93ACC54EA20B68D229C7002BC29D54E35991117CE3DA525ECF7D6CDE69CA2B6FB1C08173CDDEE5194FF5945AAB4B45B59D64734704847D3622D652A497793AA730DF4FDC5B75E084074E3210FAE181DDAA5B32BAF844207EDCBCEA37C2482171C7CB91248AF62CCBBED27129A7BB676EAE246CB59FEAE530BD5C72086946176804712938EBA0E99C34E3DC795EA508771601AA70A5C7F8747EA51EE21E9491CBF904E88EF42775F83943CC72D0BF41169C82332061CD50FBECB6C4E1B6BA22680D85711E2A569BFA42307CB750E462B92AB1DFF342F0248BA5B341A2061CFE36D91200C10999E2962B1A14CB2763EFA1D473B28DA99ACE0A1D6F3B1CE0754ED403255D9DEA1644DEABCA080D1686160D7D0AA4BFCF0E2E92B1425153429D1A9E6B08BD0700F40999A0AB9C548CF2238F3B5412C612DACBF626EC1906E1B4334904E53342C914350783F39252E760B0D6C1CF5AB248B0245AC7CBB5C18FF86475323C2F003E6E219E08EAEAB6FEF5DA019114C04180F078CADA627B +ss = DC5408384C412EFE0E18E8BDCF488CF5D0534867A416A697 + +count = 60 +seed = 99A9CDBFC674AB3FF2C64CDED7D697A6E27A767434A47AFF7C3FBF3C6A22D6043D27868955286A13EFE3DE36D22EC48E +pk = 3D3C688B33D04EBD52BB6946B4BFBB78AE03F1622B44BCBD4B86553F22EB09EC53753A300DD3827F3BCD11CBEA41987956A41207BB82A078E792D3DEB8E8193FC52ED8014B18D122818B7FD268EE02470F697ACA38E944A40BC665133C40BA924AE00D6EBD5EA4E064C64DA1AE2D60302AA8EC65E78FDC789F4CEB0C8D0B2C0A843C65DEB65824CD506F67563D991E32D88A8E0D2B70C18A4E2A69CAABAFA80FCF885CC919EC8CF45CBE74A5FA138C28714EEE6F472226F30755185001FBB915CCA2C92DB7FE81ECE68FB0F74692320844BCB75D8D17D990D6BA467F37AA542F531C5918B4CBBEE2818DECF1F42C27696BD37F6A1DDEC8095EFE7B0FB9CC78E72B500F1FC536B199209B2A80A7639FB3FE309545FAB6A5B6CA8E8C54F677FF76B41D90302B3A018777845E1C9ABAC2FABA497F41F0AEFF20E4252BDD6CC3168990E1F22BBE6FF1F3D35D9861541DAC57757D3A0F19DE74C719D988549BF9D5989D71F7A76FA44E34AABCB1ABC66C947E9CC0B0740FFC6EA93E1C +sk = 47CA2B77C5B717F423222C2730CA5CB9C856BC951D01B2B28F1481D7CAB000E33FA07DE8DC9627A85E76FABB4428A3376E66300CF12A07073D3C688B33D04EBD52BB6946B4BFBB78AE03F1622B44BCBD4B86553F22EB09EC53753A300DD3827F3BCD11CBEA41987956A41207BB82A078E792D3DEB8E8193FC52ED8014B18D122818B7FD268EE02470F697ACA38E944A40BC665133C40BA924AE00D6EBD5EA4E064C64DA1AE2D60302AA8EC65E78FDC789F4CEB0C8D0B2C0A843C65DEB65824CD506F67563D991E32D88A8E0D2B70C18A4E2A69CAABAFA80FCF885CC919EC8CF45CBE74A5FA138C28714EEE6F472226F30755185001FBB915CCA2C92DB7FE81ECE68FB0F74692320844BCB75D8D17D990D6BA467F37AA542F531C5918B4CBBEE2818DECF1F42C27696BD37F6A1DDEC8095EFE7B0FB9CC78E72B500F1FC536B199209B2A80A7639FB3FE309545FAB6A5B6CA8E8C54F677FF76B41D90302B3A018777845E1C9ABAC2FABA497F41F0AEFF20E4252BDD6CC3168990E1F22BBE6FF1F3D35D9861541DAC57757D3A0F19DE74C719D988549BF9D5989D71F7A76FA44E34AABCB1ABC66C947E9CC0B0740FFC6EA93E1C +ct = E2E61AB7F3D376CCEAC5B399CAE8A430325725639B2730F9066DAA5A02EB2E56D360D63D4B482A022D13EA5E8583F21F785B9DF2B337E2BD1D068E7010891CDE053CDBAACEC626E8D5CD4E790E7AAA89DCF09A47797C4486829CA14A42DAA17AD310D2D8894AF6867C975A390FBBFDDCF18023E285FAAE5411C2F17E7430684929D8D2E3C347D71B8B3E60BC7197C05462CC03581D61DACF6E88C6FBD4D972AB86BF4C63949516DEB71C4097E7188398DDFE5451D6441227E8E1CB771EC1B6423379E53AF1821356DA7960FE0E1E512A6394D810156624C845789063FAAA54A91D157518763012C51F3AB883E51FCF39127E74FE8E948B38654C9B3146CDEBBB804E6A4AEFBD565FC4966E06A2EEAC15AD4EA60BBDFBD908B1C67D29AA29100E146839B40AFAB1BE1B411F0D34813D4F9E9FA8C9CE8986E342C03541AC1300E099A265ED7E3D8B4B7E67D3CD83AE2AD7580E39E7563069F7FF2D99C5793F9EF7B0ECCA19DD8DC2C4116FD86ADFEBB5C2D3F202F82AEF6EE7E2290A369BE301C7A3C56D272AC27301F477C2E52D314279E93A +ss = 6EDF4309E3AC18F07A764E64386AEEC8750E934997BF8684 + +count = 61 +seed = C799D57B41F28C5C446DFC58A5AC6499C4BCF3C162AFD2B09A16549826EC2A6F689E44BAFC4ACC82F5D6AEC23F4A3993 +pk = D1EB446EF2BAF3602E244109EA6AAB12BF0207480F96292D837C2651E04C7851AB5C968D410EB824E170C9B84D47F372798559199FD6BD9B688ED23DF3E1305B65CC4392917C2464FA51193A1507C7BD716F447A55D17A389175962630496069D482423E00E86163A88F3ECEC0C88D3885F050F5929632CFA314E6FAE413D0E043359B9FC11C9605BD5548984C215C994BA08E27119AFB29876ED94DB3D381CDE9E0FBE06A6A421CCABF0E3742390B5AE21B3D11C3616C6250E6CDD2161E250E13DB6EA8AB2EB40FB05C551BD31C0E140933FAA5C408BF80600A812C39A3F0A250F305CC3C6D451991496E9AE2CECA372893B47F0D14043C7CD5B70CD719179C3CD03E86F5A072A92761DFB368E13FE4960994362371D1F7CB64BA11B8E3AE336DCF73C7D4C2CA816894C518D60F7D6ADC20285F2C70EB0A56BF264DC87344F29D1D4D660510CD0E66C483E0BF3450FDF5DB28EC764754B305583026F79B4E7A900158236605F47E546E26D2DFA249950F09A414439717524008 +sk = AAF6EB40E596A5E3E8218871E708B089240DCBE7FD3641F0E2F8D320AC3CB0C52EFDC753282F092BC39BAF4A18783A48EA031A191865EB08D1EB446EF2BAF3602E244109EA6AAB12BF0207480F96292D837C2651E04C7851AB5C968D410EB824E170C9B84D47F372798559199FD6BD9B688ED23DF3E1305B65CC4392917C2464FA51193A1507C7BD716F447A55D17A389175962630496069D482423E00E86163A88F3ECEC0C88D3885F050F5929632CFA314E6FAE413D0E043359B9FC11C9605BD5548984C215C994BA08E27119AFB29876ED94DB3D381CDE9E0FBE06A6A421CCABF0E3742390B5AE21B3D11C3616C6250E6CDD2161E250E13DB6EA8AB2EB40FB05C551BD31C0E140933FAA5C408BF80600A812C39A3F0A250F305CC3C6D451991496E9AE2CECA372893B47F0D14043C7CD5B70CD719179C3CD03E86F5A072A92761DFB368E13FE4960994362371D1F7CB64BA11B8E3AE336DCF73C7D4C2CA816894C518D60F7D6ADC20285F2C70EB0A56BF264DC87344F29D1D4D660510CD0E66C483E0BF3450FDF5DB28EC764754B305583026F79B4E7A900158236605F47E546E26D2DFA249950F09A414439717524008 +ct = B2403DDD35C1BB4FB11F092612BAF1B8B634869E09A0B742AE7FDFF1E6AB9A91AB7E1664562FA391FBAE15D362B82159F023279D1644C8FA35EE07F8EA4A0A60E5CB075434362E36FC206DB82CD755B02CCADF8C207B431A8532028EF5B49C3E04785B5501A4E7447BA3E37EBACAFCB5099AC87B483462E95B0B7633A33E28E455FE8DCC64EA4AD113F51D836073B5B9803F10FB893AC5C51CAD14A39C5C231A602BC22F27C71E99A394A273FBA9D1C27FA5E274809396CB8294C6151C63A77DCF19B67FFB59F9D5C757ABC47184F9EA8FD1927E9AB8018AC1CF51436F9B0DA722DA4321241002A1BBA555FB6FDFA3AC8495E69F3ACA9F6B077AFE283065CAA0EE357CAF662D1BEE3CD346B7E42B0A9A24F814A289F7B9BF03DBFF14A3C7909CB51A12A2C30B7DA004761CDCA96B7247F2A749842A6DB50424FB0A68AB617D998F8838E15F9065DE8503E07C774843CC712D5B297DC512E19F5C9FC1C758A6E90E10C191322DA1A699FEA371884AA94DD559B245B0E16505F700D09659714F3EC88C3D86DA1265E324D14F7F5245E2BBC56A +ss = 74900EF600281F369AA1B1D1472FBE03D608C826E33CACDB + +count = 62 +seed = F7AE036A0176A9DE9A036A542DD2840033277C44AE936D10B768566216DE9D4395CD42B116873B69D9804BA6CCBC05D5 +pk = B90B8741AE5F12DD55EF5848E232BA0D8E116993A2D12C8DA825F7A7D799B172AA87B9182D60081D3E821A2718E74C28ECB1F2ED63FD97A2580B8442FF4D1E6C53DE038E57403DD3E1F7EFA01840B9F45A496176A16C946BE9164F81DB8C0815A170A1A9D11D797865134EEDA2788164C09A82FB2C10955D009DB09BEB0959A696E7658B03B0FADE41E465E1901EB55E79F91D18EBD038B8EBADA69759A99EB5B0D738DF6DE3597D9ED013BAE470A2642BA33372F95D5DF5F4AA97CD0480D014448F33E39EC7A98DEF6AFA4D731B375A3D82090A8056EA26184BA3F11AEE82F5183E37A74DA7F11543415C4583D1B512FE4B8490AB49024A40E8501E06B34455E6B896EACFC64D7D5E2D731CC18331B2C986539D568F458A70792D1E24B3A042DDB34F4A3549F0CCE8B9EBDD03CDCA08A389BAFFFC022650A21A2D6961BD3C2DF6F4D5B640D3E74BBC468AA6C360BDD42CCBB6F4C4788431AE00C1259CF199A5941CBB057679BA413323C402AF9FA2BC707370240EB02D26642D +sk = 6500F32C93415CFDBC0BD31D78D5BE95CB9060C8CFA20139393308641A9A4647F230201E1389624A296B55192A9819FCB19AB77C25F95405B90B8741AE5F12DD55EF5848E232BA0D8E116993A2D12C8DA825F7A7D799B172AA87B9182D60081D3E821A2718E74C28ECB1F2ED63FD97A2580B8442FF4D1E6C53DE038E57403DD3E1F7EFA01840B9F45A496176A16C946BE9164F81DB8C0815A170A1A9D11D797865134EEDA2788164C09A82FB2C10955D009DB09BEB0959A696E7658B03B0FADE41E465E1901EB55E79F91D18EBD038B8EBADA69759A99EB5B0D738DF6DE3597D9ED013BAE470A2642BA33372F95D5DF5F4AA97CD0480D014448F33E39EC7A98DEF6AFA4D731B375A3D82090A8056EA26184BA3F11AEE82F5183E37A74DA7F11543415C4583D1B512FE4B8490AB49024A40E8501E06B34455E6B896EACFC64D7D5E2D731CC18331B2C986539D568F458A70792D1E24B3A042DDB34F4A3549F0CCE8B9EBDD03CDCA08A389BAFFFC022650A21A2D6961BD3C2DF6F4D5B640D3E74BBC468AA6C360BDD42CCBB6F4C4788431AE00C1259CF199A5941CBB057679BA413323C402AF9FA2BC707370240EB02D26642D +ct = 818C523C10EAE59B093DFEDC3083B4AEA2F86DD8F902CB935D5F984FBA9C2E453F971B90EC326CD02B3C6C5FA25CD3D5D3ED3CC2D463DD7D5550427E0A0A3E387609BEEE98F723C9124B16D7B59955488EE008C40A25F7F7F6E6621A826169F7E8F01382AF6C5F49136742C61899A97B38376E35DBA5E65E391A5951B91B86CFEB066E80D82B06A0C0F5ECF326A411A2E5C49F58CA6B1F95DC7E79AEF474BCB1E485836E2F220FCF29CC5CEEDDE1C2D374B27A116B84BAEA728C88F51399AC8FF101F384A9AEE0FEB03CEC12873B406F486E8D64DD15F65A475A91E5F98337CEFE2861AB2C63C291DB14242BC0D0892BFC929CE0ABDECDAA4C2B05118C4300D69334679C64662F0E34321941A0E5BA638259A2410EC56D18204A96837F5A0C186F9D0436FFBFEA8612DE6F665765A875E676056EDF700A0E0F102D0889E7D0A93238013D38D7C9BE7312D1C96C9960FD3C28A6C62D874155AB1672D4B09D4F1D051FBBD9863CCC80B20A50966E4659DD03265816080E6BB614222D63AECFFA58C2A94539700CEB3A825E4B5B0041CD1610E2 +ss = 45EFF041C387924E111B34C419C409635FB2F40B78F975BA + +count = 63 +seed = D995D38F934B6E1A7CA77C9522E3D037676CC939B0C8BD4B84394B3DC91A791F09D2D97199258C9943DA955E7F7B26FC +pk = 15410A1BA1E8219D746C3D0E7DCE545773874DA03DCE1B66FEE732E33D60530E8E4D0CCD522766B322E0C3128E0658A592C8C032F43BC4C54B62E978BEF61330E6FB36796FF7362B8F4290A0FE1180A984405CE2D6877463CB889B4FFFD3E3338D69DC0D55BD915B66D3798A49063B244D0672B2D61CFDFB4CDFDE4D2A0E108DF71BCFB856D2F6791FA4677CE293F1E5CE95EC0A9E6C0B4F5A32EA8F25EB37BF942BC8C2636ADB01B1413295D08BA9ED60BA65871EEC91A4D1EBD1950972639D1A55EAD5B57A800F6079EFDB8927D7E47796510C57F80F7A46C8E45169EF34E163860250E418FA8C324EC74EE818894B15171ADB878C7EE6FAEDE81636E698172E2CCBF72A9AA8D9E6520CD06B54D2B85F79F79F3E5D0E14ECD4697CA09D759361B88925E64EBC059580FEAE9677724F1C61FD481F7DED2C1BDB2A914513A96FF263099C8119DAE66FE660E98F0407FE906F877191CE809F41DE6D8017DBB91410CA3CA00C1CA679211B130D938B37A00109FD9D1E6725CA2832 +sk = 7643CEF2D62CC5AAEECF754653EA62294CD2208E5BF3DDEEEAC9D531A532770837A854B4F5531F6E0C8D6C10183B30D3435498C2DD14290115410A1BA1E8219D746C3D0E7DCE545773874DA03DCE1B66FEE732E33D60530E8E4D0CCD522766B322E0C3128E0658A592C8C032F43BC4C54B62E978BEF61330E6FB36796FF7362B8F4290A0FE1180A984405CE2D6877463CB889B4FFFD3E3338D69DC0D55BD915B66D3798A49063B244D0672B2D61CFDFB4CDFDE4D2A0E108DF71BCFB856D2F6791FA4677CE293F1E5CE95EC0A9E6C0B4F5A32EA8F25EB37BF942BC8C2636ADB01B1413295D08BA9ED60BA65871EEC91A4D1EBD1950972639D1A55EAD5B57A800F6079EFDB8927D7E47796510C57F80F7A46C8E45169EF34E163860250E418FA8C324EC74EE818894B15171ADB878C7EE6FAEDE81636E698172E2CCBF72A9AA8D9E6520CD06B54D2B85F79F79F3E5D0E14ECD4697CA09D759361B88925E64EBC059580FEAE9677724F1C61FD481F7DED2C1BDB2A914513A96FF263099C8119DAE66FE660E98F0407FE906F877191CE809F41DE6D8017DBB91410CA3CA00C1CA679211B130D938B37A00109FD9D1E6725CA2832 +ct = 45BE3AF36D2C46DE00A1A108135B8A756EB76C9E6CA13D05BF3F915C0704855726AC6254DCC117CF2A22D29DFC8E227506AB9830E39088D8C23E7DDA5A2235D521533A83890FBDC2EA2487E5AC9A37CA1076DAA030ADBC8873CF3B3F8F911926AAEA74A622AF57174346ADA98ADC9551087566FD880AEE8C5B2A6086B422053C65AD7C871D06F0CDB2B5E85C9AC3329B8FEDFE6937C6AB0C6E8BF95DA6EC9899D6BFEB39616881C22D14F6F66464BE2BBF59A6F424D3A2D4814EC7D30643A0271F22723A63CFA64D701A93E2FBE3A431AB3C549E0E063A426ED1ABFF7B617F0B475710E6B8D402567D893BB21B3C1FD0035D6626C96DAB854D9FEF2E2A30B1A8EA2C24D6EC76F66D0610C46A4AD44D02F501E3FCCCD7A826586B9AACC654CD1D5E258D568E04077E145D5F1467CDE788DD36C22B710684D8B68C1A85049CCC3F6769E6CF55A1A236661B86D940B7AF3E2C48497663E5DD6D3134FD7C79235988EE40F3D5BABC34229CB98C597AC74E745DF822D119421AC43B19705D0004FA92261EDECAE0058D3992864E50FA3D564D9B97 +ss = 6709B260549C1BBAFB6A97C9034D8F67ED3F62BB1BC80C1F + +count = 64 +seed = 5929F02A271725CB40200DE32D9D03D8BEA53B53AC83186C42C7F565CCB1CA508305D470850CF86E9B2C61A5B8CA1C93 +pk = 93D631D8B20BBCEEDF747C9C0F11E3FC1D4FF941918FF83BE03E82E940E900E6834E677253BDD5A9D31DCB51583E8B03BD5D77BEB07EE5C7EB5970C191FF30640A7AF99E215E2E7869DACB85FCE00EC81E63541FE5715CD32C42403D5A030ABE7DD6AA7C01EC3887091663ADAA63749FA9B4EA3CE9AC7162D3DC17E52F1CDC266A4515142C338B46EAEBF57EAD51843BC280014A4614051A34EC19AB00D8D959394CDBA9CBF3316338B45051B941BE8AAED12CF6E9E28A3DE508A8CF2CEE34817C1544E8EB5225A52589C0CB12BB6F4A9ACA0391FC113662F96D292C584E5484304C33B1D574EBE590C3C115AA4C53F8320A0D6D81028D007D0F7A103A97555844362583770698FE8CBC3E57A3559E11A70EC507BC4363D99620C4CB86029A94C72964445C0BC9827F55CF4CE36674D7B8F6F93C226261FF8BE517FA637486BE6B23D88F9CDB9C001BA4041E72257744480FD8B302F7E45C8417C976B8A12609CA55853A6C0E77BC58D26218FA3619678F0CC51D2770BE509605 +sk = F8EE95521060C03BB8DACC79F7EB7DB640F545F315613A353FC3D8392CB53F36ED647364A04E37278A0E0A45B720F4A75C580C9920EBA90D93D631D8B20BBCEEDF747C9C0F11E3FC1D4FF941918FF83BE03E82E940E900E6834E677253BDD5A9D31DCB51583E8B03BD5D77BEB07EE5C7EB5970C191FF30640A7AF99E215E2E7869DACB85FCE00EC81E63541FE5715CD32C42403D5A030ABE7DD6AA7C01EC3887091663ADAA63749FA9B4EA3CE9AC7162D3DC17E52F1CDC266A4515142C338B46EAEBF57EAD51843BC280014A4614051A34EC19AB00D8D959394CDBA9CBF3316338B45051B941BE8AAED12CF6E9E28A3DE508A8CF2CEE34817C1544E8EB5225A52589C0CB12BB6F4A9ACA0391FC113662F96D292C584E5484304C33B1D574EBE590C3C115AA4C53F8320A0D6D81028D007D0F7A103A97555844362583770698FE8CBC3E57A3559E11A70EC507BC4363D99620C4CB86029A94C72964445C0BC9827F55CF4CE36674D7B8F6F93C226261FF8BE517FA637486BE6B23D88F9CDB9C001BA4041E72257744480FD8B302F7E45C8417C976B8A12609CA55853A6C0E77BC58D26218FA3619678F0CC51D2770BE509605 +ct = 2EB25AB9DAF02C1E7F017BA2116349D66A014BABE29A6DE265B49D2DD620E6FF41586A93A7220319E4EA9C09FC272F2BAE6CE7122D11D79E9C51E46DA2DB24411DEDE56F888EF40CCDA80E3C67A9DCDD7ADF46EEDFEB6E702925E6D18D69BE70F354A2B18D597753B6D1A00B70FD72653E7222E4B8AED63EBCE5D826640C8FB78A77C46B0B42F06736DFD8DF8A4D4BB1D4EFB0D4634A241834CA7DB6C8A5DD19644E8BFF702DE1BA648F589591DD3A2398250138E66C859CA8FF3E413C0ED7E44BAA1F953CD66D5FEAC1B80492685EE4FDEF0D2FE24FC1BD0881795794A29C4CEAD837678501AB3F42F6CD19CCD744352F28B603F300D5F1B820132D7DD857013292E7E2C03A3CD61E51BC2EAD30A7437DB584B408C4EEC30CE3B49E742111814E6D8509AE6CE64440C22D64C0197BD0EB968237A889ECDEDA472D5C209E57EA88E398E4F0852B9C38EF27D32DD50407FB29EEF3348D77A8D3A1AC727C2B713B14A4836B8FEB4EE168BE1AAE4B237260A64BDF97CDDCF41CC7061073F848B97B5A58A99CC4358EF9A04BAD573586B67AE761 +ss = DC80EF72E53CB172CB6E9290CD310350E8304DC71BA1C17A + +count = 65 +seed = 905074033D7B75DEB2D06A2F29144EB377B452534C5710632989F02D45312D156557E96D4486020826DB200153BC4A8B +pk = 630F5938E8EB2CF9870133861FD28529930BE4A3167509F385128932428D6E3E6C4CB75AD1BDDB878FC64B1A15D83938590C20889D9507149457732BC5383832B705FD4C1618A287455BCB1B320A05B81F991C2585D003DE13216C2DDCF73E967E89D3D372CD009BCD27735784A74396125228BD4EFDE8E04A50C259FB24D25341567DA6C21136AA40C89943057E33E2224B3DFC149A144BA126B6982A12D61839AECC276DE4C4E145FF5D2396A308A368AD852F05D2FAA51FA57D250E67DD5E3BFBBD76C68ABD9954A11415B42959C8F583FFF91A22D18C0787C8E6EED9C371AB2CCE10C633FB6381A03517B142314E022404E72266064D25B978133B3240262C99968004F954F1B6C21C565C373BA4795CE60345CA3D90AA951AB5E5AA4A6E005234D72887EF6CBBE4A4FF38DF2AEC1BE3CD4D051ED24FF1D31684EB14A8329CA28610DAE6D6684992F09B36D1F42BFBD6174DEC4CFCBBF345973AC1D2F550CA5C421F12D61CBD2ABF78C9D1D55E6C965D49E7FF31B2B04040 +sk = B8BD0493A882E3A49B4E0F6256FB1FEA0912562FD9BA26ECD7E4B5D8021C486B9C3114D7CBBEB7CD49EBA8A61BC2BCAE1F1BEF30A1DAF70D630F5938E8EB2CF9870133861FD28529930BE4A3167509F385128932428D6E3E6C4CB75AD1BDDB878FC64B1A15D83938590C20889D9507149457732BC5383832B705FD4C1618A287455BCB1B320A05B81F991C2585D003DE13216C2DDCF73E967E89D3D372CD009BCD27735784A74396125228BD4EFDE8E04A50C259FB24D25341567DA6C21136AA40C89943057E33E2224B3DFC149A144BA126B6982A12D61839AECC276DE4C4E145FF5D2396A308A368AD852F05D2FAA51FA57D250E67DD5E3BFBBD76C68ABD9954A11415B42959C8F583FFF91A22D18C0787C8E6EED9C371AB2CCE10C633FB6381A03517B142314E022404E72266064D25B978133B3240262C99968004F954F1B6C21C565C373BA4795CE60345CA3D90AA951AB5E5AA4A6E005234D72887EF6CBBE4A4FF38DF2AEC1BE3CD4D051ED24FF1D31684EB14A8329CA28610DAE6D6684992F09B36D1F42BFBD6174DEC4CFCBBF345973AC1D2F550CA5C421F12D61CBD2ABF78C9D1D55E6C965D49E7FF31B2B04040 +ct = 4D5DD6632ED5B0D79DB34A8E0E6606313AE97DDB80CE5551667A7AC71C727073B6AC34C5F61B7DE541659675E2FB18747E4FBA71ADC9A83029B4104270A82203D8FCCFF49B8ABA725498544F36CC2FE40485171060A3F8E1CB6BDBEA4FAD74C71676A90130379BD1590D8CDE4CC5DCC818F2981866585A68BFDC6222A52BE23C190BBD612357574E4D69192D6AD0B148FCE9E809B4047CAA681432F6C978DCE1FB5A5DA4CF1CC684C2E975A51F6B8AB6B91DABCEB31C8A5F0B71040139526D60A2E0B59D7657E0F22357E984F38E2D6B28844130F3034C1829DC0018525FC9466BEE22FD9388657019C7EBF205A1D1E59B1391CA591CDBD2590D842419A2DA22A9A01E2D75964F61C5C4CEEF33CB3A43B0316E0389B0B3FC6079DF08FFCA1C2E0378D4839D53B342C9183C25415821FE891B43941B97A4EC517009086117629C8D085A668C984B9A786E47D290962C2D7AFA8C08E803E1E453EB20861F857B77A33BBF1EF3BEA013C410EA8C647B9BCF4B1E3DFF53FBF524863B20A344EA208AA711978D4C99D84327BE76BE21A8FE3DBCD7 +ss = 59939CEE498FF3CD5B49C1203224641E4F3A0C55DD2A523A + +count = 66 +seed = A3E2E511AFA7BB560446BDADF67D2EE2E16FFC7BAEAE7EFB8C5455068BBD4E91BF9BE9D98B280072FABA7712C75B26D4 +pk = 43105C18A44661C66BA5BD3E14E2BDD34A9D4297FA897CA3F517EA39F847078232E5DBB3B8F9100DA20D55FD66A02CF46074F02D0A1F1B6DEEA7A7B403B812D74C0E8FD263F9D7BB619192B61B86FC556DDA699A906E26D199E142DA42DFB7E9ED593D93C1C055C9974E1CC2E83DA334492AE1BD045FF04D1587DB70523DC9EF35736F6011C9FCA21A82C77A8DE8727C8CE3A1D638E40F9E8906D5F574607089F63C06DF9B6C9B8272EB6240EF7E81EC0EADE3899D9E3D1A19ECFCF837636C5D8932EE84724FBE078E9D719E9BD43908B41DE54CE8AEA63C6FA99B4E2680B51DAA7427668648AF391A7BA294859728F98385A42281611A6C9325FD1E94D0D056421C53CAC7EA1C0E22BA32217DA76B648EACC7BC445085EEEC4DBC0403140D6AAB44D36F182F3340A34E25D55BC5621C0BA31413A5AE5A2181580C8779BC8F693B488CCFCD8247BE87B2A1B9CE5DECCD98F57C7FA8A22338001DBDFA058D00F01C7737CB1E00682AA436547C84AFBAEE00866BBE28E3D9C57C30 +sk = C0407E41DDF48D333978B89BCF2DB01E4613425B456249E7B2DCA81E3F5F748D23C9D356A2209F6B2D60247B2E45C9808DE497F64F12460343105C18A44661C66BA5BD3E14E2BDD34A9D4297FA897CA3F517EA39F847078232E5DBB3B8F9100DA20D55FD66A02CF46074F02D0A1F1B6DEEA7A7B403B812D74C0E8FD263F9D7BB619192B61B86FC556DDA699A906E26D199E142DA42DFB7E9ED593D93C1C055C9974E1CC2E83DA334492AE1BD045FF04D1587DB70523DC9EF35736F6011C9FCA21A82C77A8DE8727C8CE3A1D638E40F9E8906D5F574607089F63C06DF9B6C9B8272EB6240EF7E81EC0EADE3899D9E3D1A19ECFCF837636C5D8932EE84724FBE078E9D719E9BD43908B41DE54CE8AEA63C6FA99B4E2680B51DAA7427668648AF391A7BA294859728F98385A42281611A6C9325FD1E94D0D056421C53CAC7EA1C0E22BA32217DA76B648EACC7BC445085EEEC4DBC0403140D6AAB44D36F182F3340A34E25D55BC5621C0BA31413A5AE5A2181580C8779BC8F693B488CCFCD8247BE87B2A1B9CE5DECCD98F57C7FA8A22338001DBDFA058D00F01C7737CB1E00682AA436547C84AFBAEE00866BBE28E3D9C57C30 +ct = 7A9E2372AE10B005AF59A0DD576463479FC28464645C65AB169B7012CBCB959B2002D4F8A4B621CBB2056718D7281A39EDC4DDCC2F93654A84C052D14F79033D40F6D266E4F7B998D942E9282995F22452BA52F86172620B4851A9D1989A7BC844C00BE648D20E900195920E915B182E5AB61E56D7993EDCB3993C7EAC0631D3942E4B1ED6EC56DE4DF86FFDCD09D95DA78CB9438C28CC67661FD3DEB957D8B085520158C9C933295C66D306FB46499982987F8F7FB7FD5D173400F40CD76F881075D731419726349511BA5536496310B5478EBE86161268E8CF8EE7E4DFF41AF81D3C5E43EFBDB1144BFFA40DC61F16491B4913CDE26B867877BA06C7425A5F0E6A2A077CC54E893DDABF96DD04660C663008D961418CDBE9F3471DC101BA1BBEC442D83863BB2E2351BAD1E75632A0DD635A6069AADB2EBB5B05F36A3A0FD084EDFF57884F3825341DFD2A038FC896DDD2FE5E498B8C74D2A28FDE7A2E22384CF29BD799BA165CF38765F62D55C8A5B31817C10D16C5B22630EBCF371BF981999E51519BBAA9F781E50B0AB80F560B6AB5 +ss = A32F6F1DA77E156A2523D3E043F261E4D8E9483939B317C7 + +count = 67 +seed = 074AB1A37BA5A0403D8F68D26FB787BC2C90F5EF88F2A6D286C3E6B168ABD85D393D8225618608B8EEB301D26AF53BC0 +pk = FD0114CBC56E344ACFC08BBEC2841AFAFF2A1587273294CBF28E5A9B79D485C87FC4BA6D09850DFDA73E2D0F11614EC5ADEA41AA6EF548748E9206AB1F51336150D712A23EFAF3F14C9C6DED9A268DC3562C4F08C180F111B584E00B0B049ED534C33F03FCF8BEB3A6D3424B2ACF420D849099DBBDB5162A06268A95A31A8ED7AE1B672F1CCA3E0DBAB37A81CC4D806FD01EB3D71A8DB53CB26543A64C3D07196249200C13D1A45AF70412116FC1A6728EB64550D09DB65D359289CC0ADAA73A0D808725039FF1639F1D814ED05E8C1E7C6FCE727BB60033C3C41B8ECF6C31BA9E413CA29EA5F8CDC24CB03F43DA5BCD09236062A3F52B0EFE23102789F3BE9C9A87A0E5AE8BFCB32ED2850A623D7F1D7EFCFD7BA6013D6A4321C9691BF708CD62C4B18504C867653FB49CC274B1C48A88D23D3F4043F2208D0326130DE626034A6542232A81D903EDFDD89A0A4D9651EADF302926CB72871DD2887F95DBCBE6205B8BC0A8F7726A4E5C363EE3A9235F6199D208BA06785F601B +sk = 334382D39164D1989696A2FF77B25A28AF8BEAD9883B5365ABA5068AF837BE962F439F233593D193CE5E08F7D66EFB3389885927B89D2503FD0114CBC56E344ACFC08BBEC2841AFAFF2A1587273294CBF28E5A9B79D485C87FC4BA6D09850DFDA73E2D0F11614EC5ADEA41AA6EF548748E9206AB1F51336150D712A23EFAF3F14C9C6DED9A268DC3562C4F08C180F111B584E00B0B049ED534C33F03FCF8BEB3A6D3424B2ACF420D849099DBBDB5162A06268A95A31A8ED7AE1B672F1CCA3E0DBAB37A81CC4D806FD01EB3D71A8DB53CB26543A64C3D07196249200C13D1A45AF70412116FC1A6728EB64550D09DB65D359289CC0ADAA73A0D808725039FF1639F1D814ED05E8C1E7C6FCE727BB60033C3C41B8ECF6C31BA9E413CA29EA5F8CDC24CB03F43DA5BCD09236062A3F52B0EFE23102789F3BE9C9A87A0E5AE8BFCB32ED2850A623D7F1D7EFCFD7BA6013D6A4321C9691BF708CD62C4B18504C867653FB49CC274B1C48A88D23D3F4043F2208D0326130DE626034A6542232A81D903EDFDD89A0A4D9651EADF302926CB72871DD2887F95DBCBE6205B8BC0A8F7726A4E5C363EE3A9235F6199D208BA06785F601B +ct = 0AB025362EEAC2905F52F438DA0B4CB36533200FE168B46F0971428F4938F06B9D165E1060148E4DFA0360313D63B7181DB9E12C140BCD93427969059C60315CFC9859D92B399A4E125D26DB70ACAE893BA783DBF8232F5E315238AD58AB2235F3B22BAA528AFAA47BBAA2BA203BC69C9B827B5D5BB44A6A338266C0791875B8E68978C749C0AEA789B9DB3003E6AD4DADA079C8D0EB87CF2053A64E9002D1360FE42FDF6C2548C0CE5D6263CF3FA4405B2DF25D254998DBD1A2E0161CA2FFA200354FE12B5BAF8454B321B4FB73CE525585C4EA4642297BD0A12FA860EAEFFD13F74E27AD373B4F2285DB0E4FF3910A6E66A1D528A22459BA95A0159495BC262C45C93591A323BDDFC2FB0822258CBABF13B343DD95E5147199C0CCA4E426524E07C8FD66161945C25362D9A6D83E3505882C0604F8E14C964E25C9439E7AFD8E238CC330E84EB247D0205DCCA46A5B9A8271C5DAEA8A77E633276B61C9E9009F9103C75D8E91197B2F5D9604A2EADBA56D6425EDC9AC68013AD662C7F7D74A8308A9E28E68FBBC20360BCC59FEAF25013F +ss = 792F6220241942B423BAE0232B51DE055043E707FE6D3CF8 + +count = 68 +seed = CC0C86CC0ABF86FA21899BE1953913C00E7C46E6B5F730C4E88B3C034012763981D7F14459D3081638080378348856EA +pk = 6493C7F984DF0197C643B1FF30A4639BC34282D9837B02E3B989E606F765CDFDA92DF2030AC29AAC3E272DBC59186E349EF0D79F2352C328CC540CEF7F432FDC610B5E9AE4BEDF737DA5FC3213621428DF774F397AE4D18A5711912324E6C6E0102AC50939CA1C634DE3FA59B37FA5BBB14F31F1302FF6ACB3659EF61A2D0EF0091C68A237A7613087A0E4EBFB989B51C81F991F61164C378FEBB0A917CDE9FF0291635F1885A99D486E394800DE513E195755DA7D8B87C216C02C10143AA915E1725E3B95CBD7925CBEDCF69C6C980A15B2EE6CD8892B3FF619F261B3CE7F8F1B52595ED251A44A4C94FDA1D8E726A0C43D46CB539CD89D8888B32EBF5C6BB64D3D5633C4EE088C9CF27C5325D0E8F269D312FCEF568227864E44D7947557E7BBCBB6D602395604604453FFE641B51AE72F3D9994C909C9FC3923EF692EF6DE7E97858BE55239AF17AC6F1282E9811CFC8D128483B16906676AA795A57965941791D1D07047C1AEE3CEB8AA04E6218AB56AAF56E9AF1E088A14 +sk = 6995143E8EB8A6E93840F76EEC844F67D2B5F75B1839A5040F4DFF8E56F68440836A072412A30D851ACE2C7C6F02D60E7A8420001A63E6066493C7F984DF0197C643B1FF30A4639BC34282D9837B02E3B989E606F765CDFDA92DF2030AC29AAC3E272DBC59186E349EF0D79F2352C328CC540CEF7F432FDC610B5E9AE4BEDF737DA5FC3213621428DF774F397AE4D18A5711912324E6C6E0102AC50939CA1C634DE3FA59B37FA5BBB14F31F1302FF6ACB3659EF61A2D0EF0091C68A237A7613087A0E4EBFB989B51C81F991F61164C378FEBB0A917CDE9FF0291635F1885A99D486E394800DE513E195755DA7D8B87C216C02C10143AA915E1725E3B95CBD7925CBEDCF69C6C980A15B2EE6CD8892B3FF619F261B3CE7F8F1B52595ED251A44A4C94FDA1D8E726A0C43D46CB539CD89D8888B32EBF5C6BB64D3D5633C4EE088C9CF27C5325D0E8F269D312FCEF568227864E44D7947557E7BBCBB6D602395604604453FFE641B51AE72F3D9994C909C9FC3923EF692EF6DE7E97858BE55239AF17AC6F1282E9811CFC8D128483B16906676AA795A57965941791D1D07047C1AEE3CEB8AA04E6218AB56AAF56E9AF1E088A14 +ct = 6187C61B44CFDD9C1454EBF224F7091A1E7D95D196B4C038396043630D04E4C83F66ED7039C45A2B9CFD5BC913CD5E0423D13C11160DD334F613157264402871AB50A6657FFA78F829A134256992C73C2BA5A48D9D1B53744F466AC7D5836B691FAF97BA3D71AD31A5A51F21FE70D00C4DB9CF677050560A86E42EFEE80FE055FB4041B0A9574660E20442EC60C9042049C27A99A360C16335F996FA170661C74F72F71AECA77B55966E3641477B838E1EE292FF6C02095B63359D050B96A02BE431B66A0BCACB73A6CC6A41AF800597BADBDC577A8A30B2573CEB90BDA8AA79BB8A04DF9A0920394F63945C87AE58AC5CF2C575FB40AC0FF937990185ED843317642FE483C9DDA924283169DBA90C4B736D1051D07A815DABF22F7291DF81BC67845A4A98C47EB2B6402749588F70F400CED045E96B38ABE57B139C486465704F86029E8035A1B626EE6F132AB26ACCFAE34EA6A99752349EC4F4031B6EA5F590B5D30BD201712F77AFD6D98758838066C82A6EF2000D259E0D642CB441A15FF9C501A4824021F394E6A880505C9E0CEDC4 +ss = 9FB845B159F6BB1DB99708B4152E5023830D317A78ECC0C6 + +count = 69 +seed = 6D5A7CC326ECF3983C4E7683F45263A37F692F3BCD2D920E1FD9584350119E74F9A3F905F70D3E20318C1413DE2A0DEA +pk = 8437E38BA6F0F61040BE8089DD2B0551FA5EA742D89F034BF68D572CEBD0A5EB59D48DF0174208BB0CE7AC21FCC2BDA564D8888C4517CEE05CB2038A3B1A16E4C990082F466B531DDF5997F20F7B235FC0409DB0E79209D2FF376BE99E1B888A61847A3CD4823C41718E5AC05494F5FEF6AF7DEB02ED8D295014141B8315640D8299CCCE132C626A1842411C0F6661C321CB66532B2D7922494D5CAADC0BE43DD1776C8F2325B0E87AD3CC0564D4250AEDDD477394708684A371619B0D4D6CDBA0CE541F13E747A8AA7E349262DEEEFC790C1458846BB8804B23B225ACC3F11BFFAB8C7EC5622DD61307715139843B7657877917759D3389AF5C4401B88D40924D4DA99E9E5647B03534FCAA833DEC47DB24AD492850D732B1080B4BCB9D5B9BC51A6D9EB70FE893B4EB257E587C8F654A1E988D6FB54FA5994106648D140FA92EC2C92F25CF120F156960C56577827A344BB7D16CFA910988F4E11039122FEE4B61102F9B1AA938FBE4D8C057142A80275E7AC811B582599012 +sk = 995EFF7E0D195C6D0533F3DC194D47E60F9AD14696144CDEB28F7E7A15A005F92400CE33DB073D49B53871594A88FC45E0F94207B5F0F20C8437E38BA6F0F61040BE8089DD2B0551FA5EA742D89F034BF68D572CEBD0A5EB59D48DF0174208BB0CE7AC21FCC2BDA564D8888C4517CEE05CB2038A3B1A16E4C990082F466B531DDF5997F20F7B235FC0409DB0E79209D2FF376BE99E1B888A61847A3CD4823C41718E5AC05494F5FEF6AF7DEB02ED8D295014141B8315640D8299CCCE132C626A1842411C0F6661C321CB66532B2D7922494D5CAADC0BE43DD1776C8F2325B0E87AD3CC0564D4250AEDDD477394708684A371619B0D4D6CDBA0CE541F13E747A8AA7E349262DEEEFC790C1458846BB8804B23B225ACC3F11BFFAB8C7EC5622DD61307715139843B7657877917759D3389AF5C4401B88D40924D4DA99E9E5647B03534FCAA833DEC47DB24AD492850D732B1080B4BCB9D5B9BC51A6D9EB70FE893B4EB257E587C8F654A1E988D6FB54FA5994106648D140FA92EC2C92F25CF120F156960C56577827A344BB7D16CFA910988F4E11039122FEE4B61102F9B1AA938FBE4D8C057142A80275E7AC811B582599012 +ct = A3A4293B3CF0672B51D2378B896147F43DAC477A904C37465323B98F2FBD7649605DE3F78A6F8C28F6006CD81F4E7429618ECEBFF866607D3F27DFE207B52F0919DAC224D2F6AC11385F98DF2BFF0B82BF25D6FDE80D203116C8B7292D37950C6B99947E189A0863D1665542A7369A02DCAC72D71BE14A0D6E91AC038E3B2FD357FD42AF720264A425768CD250D997C91C70FE83178B9419836F6BFE84325A74A0F5FA102761B5637D11488C590A2A8885799596DE182D590D34401724CAAA04998DE75FB4459C79E9CA25CBE78A34B735DCFAF27784E9CBC92ACF52701B6CAD33499FF4BBD18293C182FC823E7E1BE3B71748ABCF711DCDA0CB071791992E5549BC3399426775EBBE1EBDDAD6E35E04D0405DE19E10A454BC2AECC4D1E4ECBB402BCC2FCAD274295FDF4F372021715DA6AC4B99689BA4A21C640A5141AC7E8FD0BCCBBE82F47B8B49FDAA6305CD5FAEEBCD35CFD7CFF5B04EBD339AD5764E8B5056CE1BFD0C5FD8EED244C49DA31D0AB3956036A8F0FE7CAD01A439FE9578055412458974222E4FAB779E9C880D3D26D52E +ss = 2020D67892B0948A4C08FFA87F6DD300270783D2C0FC5169 + +count = 70 +seed = F68FC0314DEA88F66AFAA76E6C9B6804B13D4876924410D1F526FAC59A62E26C560B125B1D0F8B461F1FC2E351EFFB4F +pk = 4FD2EEEF9F048A5B6756A69B329E954E749831135B000A390442C588A3E83E7450E300C6B18CBB7EF1B36911BC759D19E4FFFE452AF2BD2FC2928AC2364A37A74A9C172A719DCF66E7D586DF797AA4A7E1C32A71904FA7E37C4DE5428546A9BA368B34468E4A179E20DB44103F03E235C1E23A1932DD6EFFD5F39B2CD02F6AF3BD96F8AFDFD54F31118B87F720C251B961991941F41827AB730ABAD792192A514B1DD60CF9AC9D5969DCFBDABACB42C94497BAF6474522EF520F20E63BC12FC83D837A0EEA5BF8F8DC7B7A95B484E1C9C81DE2A996A49B691EFB16E88D38B055B43E7184A9804924C34B50E79C934C1A7E7DBD0E21138B8C5A18E62259259CAC978865676521E074FDA01C9F770F155381C775C94DE07038FA4EC2E1DD07FAC47C584BDDDB83C178F6B8558F7E8E76DF8E1FC6115D2A3C0DCA690AC6A8F9193DB53E7FC1AF25A5E7255573B95490D7AFEADAD9BD3F3846BBE7311D02E7E169492B2C3DB630D3FD7C5D93A37F6D676C0971584877005AC4D6BE03 +sk = 3E809EC8DD0FEC0D911A4E3FAC20F70FBB128C5DE94DC718D8128601C28B1DEF8D393A0DB283229F7C7383152A814E7CEFE8EF9D9768C4034FD2EEEF9F048A5B6756A69B329E954E749831135B000A390442C588A3E83E7450E300C6B18CBB7EF1B36911BC759D19E4FFFE452AF2BD2FC2928AC2364A37A74A9C172A719DCF66E7D586DF797AA4A7E1C32A71904FA7E37C4DE5428546A9BA368B34468E4A179E20DB44103F03E235C1E23A1932DD6EFFD5F39B2CD02F6AF3BD96F8AFDFD54F31118B87F720C251B961991941F41827AB730ABAD792192A514B1DD60CF9AC9D5969DCFBDABACB42C94497BAF6474522EF520F20E63BC12FC83D837A0EEA5BF8F8DC7B7A95B484E1C9C81DE2A996A49B691EFB16E88D38B055B43E7184A9804924C34B50E79C934C1A7E7DBD0E21138B8C5A18E62259259CAC978865676521E074FDA01C9F770F155381C775C94DE07038FA4EC2E1DD07FAC47C584BDDDB83C178F6B8558F7E8E76DF8E1FC6115D2A3C0DCA690AC6A8F9193DB53E7FC1AF25A5E7255573B95490D7AFEADAD9BD3F3846BBE7311D02E7E169492B2C3DB630D3FD7C5D93A37F6D676C0971584877005AC4D6BE03 +ct = DC64D193FEC8C9477547345294B156B57EB038AFC1ED7432E6E3483B614E16C055E5B21C76890D8CB5B7507E081528145D2F23096A4EA414783793D1858529CE53A58976E062F56110A7B653EA0FA8DDFAF6D0F4BC3A7D484B5BA754F23ED94E3C850B652755F6D4CB0F7D6B07C1CC52E212BE9E0C6841F9A67A36A44B053BA4BA9DE9281F42DB486F7485C593B1357576596DEE2BF8E96FA666E58708A1324A57F4649ED7A082CCE538E07BCF3282EF12E6EE6F477C93D2F9CB02CB255D38A08C054590AE6929AE76E5A05EEA8ADFDD55C5A108AC541D69628E774863691702AC8DF59F54726846F9AA60930A207204E5399CA045955C831B0C0234EE81ACFD963CAAAC7B2FBF0AD575FB9C81E008D9B59304BE04EF8970024EC00E39BDA5497F75688470B79CFE20707601D6DACB139C237B246B5E504BB89E2FAFE6787237F893AC34528181530CCC29342A494C838E8EB56BEF2E8F4F1255304DBF3B6A4DEFE641FDA73F596481682D5A791AD49FD522FB279CFA80FCD1316CB80BBC123607330020F0B8CDE24FF1C9ABB2A1B4C645D8 +ss = 4850D52145D1B8A34A6E725E8531DAC658A18CFC94C44B4A + +count = 71 +seed = A229218B0D51F58D915DF549901548FB0722F352C7470900E7E4D8399205764A319BBDDBD06C00E8C5932722EE5A404D +pk = 2EE74BB65B8AF7F24CD138AE652C28FC6C70FE5F90C25718CA5D0B603825127A24F2BB909C00724FCB0F0545490ACC812C520EE8D17258383D46571377E63C224F17960AAC40B58330C850861EA35DF382ECDEB1E3EF666C54C3DC6DF85FAFA82E69C121BA98006264F72CB8EBDEB9A26D6F2848425170A46B7B62690D069C4FF34280D88F870A58C9E9A7E6FF80AF011C634DD47D385256788AC9111234383C22237B9795587032371BDDA68F35286CE405AC08711700283EBDA1E0010FA9D7141DB3FE5612CD31DAD69A0CC00C96F4707131904ED4641FEE9B877198F0526C3160CFD1564CFF72C9E9490B332D86B575906C7EC4CB05B14573D11F44F624A9B7B3D4AC3BB5D700A485A8073A887A2CA65435F4880870D071663C2867E882C801E8005F6F526E678B1495E64B688B7A0AD1DCB493160B96941832C79E0CBAD492DC765521D93302E058D1A5035D02BA884FEB3267FCF4F71697249151E2419EBEA0CEB020517D6D46697108FA99DE57968C8831D1E0AD280B36 +sk = DBF1C465FFF3D9F783BD9EE61A573715E45691147B890443B6D75EAC6C76CED1B0A025B40A55440712AD8424672E761E9BC400D63812000F2EE74BB65B8AF7F24CD138AE652C28FC6C70FE5F90C25718CA5D0B603825127A24F2BB909C00724FCB0F0545490ACC812C520EE8D17258383D46571377E63C224F17960AAC40B58330C850861EA35DF382ECDEB1E3EF666C54C3DC6DF85FAFA82E69C121BA98006264F72CB8EBDEB9A26D6F2848425170A46B7B62690D069C4FF34280D88F870A58C9E9A7E6FF80AF011C634DD47D385256788AC9111234383C22237B9795587032371BDDA68F35286CE405AC08711700283EBDA1E0010FA9D7141DB3FE5612CD31DAD69A0CC00C96F4707131904ED4641FEE9B877198F0526C3160CFD1564CFF72C9E9490B332D86B575906C7EC4CB05B14573D11F44F624A9B7B3D4AC3BB5D700A485A8073A887A2CA65435F4880870D071663C2867E882C801E8005F6F526E678B1495E64B688B7A0AD1DCB493160B96941832C79E0CBAD492DC765521D93302E058D1A5035D02BA884FEB3267FCF4F71697249151E2419EBEA0CEB020517D6D46697108FA99DE57968C8831D1E0AD280B36 +ct = 7D035A9067DCE3B2B6F00D702F53BEDDB35C923A3AE916E37D962EC6C233179A34C480389077684C5ADBCF21EE26DBC6A1842953CCE435323738F8CFA95C1C35F3175471560093D96E924E11C760C56AC0B81E5C2424581BC4168C74B651E60C3BCC81BE532A46739276EB8A72B68B20EAB9BD3822650984B71D79692D11F2F3813CB799655864BC01968056B244D03A6954B929ECE09677625196BC0ABC855FD1653D90CBAD4B8AE005E6379DE237931DD5EF66B7FE6F1FB265C24715E5002EC98D1FDD90647CE9068A9A342AEE127CBAE774DE2C3CF5D7CD6F8AF0C5216362159BBE38BC15C714D614483DA782183239094866DA12E032486E6600180D6BAFE3FA528902550949A6058D50273357E776E86D24778E4A5BDC1956A5F303BA66EA3614FBC2C5D3086EA959AF2FA111399EFB43217D17A243CA2B02773E9356EAA52CD3F53ABFE3C832BE179D9F25547269493E9BBEF6FA4D9C27825D50A698867AEC3CB84148CCB319905758A7846BD33880009401A6A2660F3581791B7B212EDA2DB80CB55DE63352FA5519675E319DE072 +ss = FFA07CF6EDDE214FFF98EA251C4DEE8614E7CA2B0045E59F + +count = 72 +seed = 6960F21C7350DCF41B4770C551DC8692D8BA2C0B6E162C589166FF22E7A1AC0F94C2F48504A5F7EB0DA094DF427BC98A +pk = 26FC81335BB62FE0AB13A39CF601FDF65F6ABB7E3A82FBA61EAC00D831E4B6AC93B8EC7C728EFF00238115FB01A8FEAB7C6A941478599129CA9D0126627528174D1788C138D8307BF29D0C273264F670498E8E32751D68BAE6A2F0F71097302EA6BD36F299C9E7FD70993173770DF0F7CF2145157B65C041062766800E3274B1F71CE13C2A4FF798C2881CC0F5386F7715C126B02212881018E10FB8DDC292D49F4533476DD1C183D7F960F7D3E2A39E06AEE8F814B289F3A972162719405FE9E6D0B09EFF98F792B6FEAE945F3E391D40A06AEF02088E2EC68C19313483245D13BBDF4692F92AC826AB663D9969A2AA5B4E67D0F3E4A3DC2FFA171FA05C9BC58E6EB24B6FF30B9E0EDFF6074B5C85870951F272528A452B3D98C747A7376272D50E4190BBB4F5FD84B3DCAE041BA70FAA9BB5DE79D90F564E292E16610B94E7CF42EEB7AB34FAB79A8BFECE6757F42E2415A6DF09B0EC673B796069EB4F74E7D5098F72975D47FB6A4DDE58511E34730C917F2A2554A2682C11 +sk = 1F7CFD2B70863154E8A69D1758532E86C20CFC763D67C758273B38BDDC18488024EC90E62A4110129A42A16D2A93C45439888E760086040626FC81335BB62FE0AB13A39CF601FDF65F6ABB7E3A82FBA61EAC00D831E4B6AC93B8EC7C728EFF00238115FB01A8FEAB7C6A941478599129CA9D0126627528174D1788C138D8307BF29D0C273264F670498E8E32751D68BAE6A2F0F71097302EA6BD36F299C9E7FD70993173770DF0F7CF2145157B65C041062766800E3274B1F71CE13C2A4FF798C2881CC0F5386F7715C126B02212881018E10FB8DDC292D49F4533476DD1C183D7F960F7D3E2A39E06AEE8F814B289F3A972162719405FE9E6D0B09EFF98F792B6FEAE945F3E391D40A06AEF02088E2EC68C19313483245D13BBDF4692F92AC826AB663D9969A2AA5B4E67D0F3E4A3DC2FFA171FA05C9BC58E6EB24B6FF30B9E0EDFF6074B5C85870951F272528A452B3D98C747A7376272D50E4190BBB4F5FD84B3DCAE041BA70FAA9BB5DE79D90F564E292E16610B94E7CF42EEB7AB34FAB79A8BFECE6757F42E2415A6DF09B0EC673B796069EB4F74E7D5098F72975D47FB6A4DDE58511E34730C917F2A2554A2682C11 +ct = EFEC0492F65D5A55E47871DA5F3BAB80B5BA18D0E4E00D5DF1B3BD098AACED2D4F9E311C2A1F91EA42D4FA8AFCF6E88FD1EBA1ED4BBDAB5B624684F115D926ED2E9CE3937974EC4CA37D481423049717E146AB470EEB0DABC9CCCD9A2213F0A6432B7537B52E9626540E7B3E9755851663C1A86205B08E3C8798D671A40BCA34252F3AC33C4A61D237A7C563761EE5C8FAE5EEAC54EF22CFE6D9956BD7C9216987231CF6B41A5B10D2D4193708C30D8613C96198C384A6C20D8191E411633868215C3AEB17199E1D043C1270BF322C7C568F36F2AE64758FE79ED35C679FF65F2DA924182C517A58D1C0497084CFE569B802A76D4001CD010A763908B191A8958092B441E38A7B5CDCB8686709C75A92EA9485C99F7EB05E0A31D9AA34857776C0FA32EBFE96C15106B5971155AF1ED4795F0C40948EAC8847442495204403F5333C5102849A8A53DA985BDFEF105A11AE2F123DE8831D7746CA6F24B2CB12A00C51D121844C5306C53D8460C86E7083B1E211D6B93082103A02C55191C85EB56A3E4E1FF4C85FE53C1F2662AEBA05369954 +ss = BA828873D946191AE2D6823F33E0A97B19BD4FDFFE0528BE + +count = 73 +seed = 53DF46012CAD4A745B7A3C06E18CA95E0B839FD8161E3025749A0887549EB0ED6A44EEEA08BD6060D6509DBF7E9DC864 +pk = 45CC88C2550E06BACF0409CD9D8086FC025B1927261865AD475387971607DFFF19CDF9D814557A0563B94A802D140E90EAC5CF3FDC500176E436044CEE8D08894FA5894B51818648A7E4B3098A20D8AD1B29514E8D42F9894FCA017850F5BCA83A77B6C93896804D522D7FBA974FBB1769E8AA4C9C9EE99BE3D95DB7BE10932E5FF009460C0E83475E786CE6C0879585C84410E2EE14C86E68A49C23695E276A407CDAE3A9C6C97244A557E176B890C29E7D201C9391E31BDA550F390D238B0C93866ECD7947C2710E7930B0CB006DF15344A5A53D2C5F4A3935CE5A5320F6F8434D380237C91C72EEA6653EE2410D4A9A6E3C3E8D73EC6E26CDDB193CB93A773F9925FE1BB7379328A71DB0330DCEF9D5EDD75BF5E141366085E4DA600C5C07FC2B088A18F2216DC95200302B3DCFFA711474D8B8F1B6A1826B053872AFAE3E57D35C5E4E79ADE2E5AD0F4062B6F0414C4A62B003C3BE40661A68C20845B24A8F36A21EB453738F3C8337D975ADA8975B9EBC33188CB614772A +sk = 3A19577908EFD37697B8EDC7FDAF47D1BD3AD01A1B77FAF7A3729672816F3EBA84C9638A79676EEAC0F22C8A48E0C5D50A26FF0844C66B0945CC88C2550E06BACF0409CD9D8086FC025B1927261865AD475387971607DFFF19CDF9D814557A0563B94A802D140E90EAC5CF3FDC500176E436044CEE8D08894FA5894B51818648A7E4B3098A20D8AD1B29514E8D42F9894FCA017850F5BCA83A77B6C93896804D522D7FBA974FBB1769E8AA4C9C9EE99BE3D95DB7BE10932E5FF009460C0E83475E786CE6C0879585C84410E2EE14C86E68A49C23695E276A407CDAE3A9C6C97244A557E176B890C29E7D201C9391E31BDA550F390D238B0C93866ECD7947C2710E7930B0CB006DF15344A5A53D2C5F4A3935CE5A5320F6F8434D380237C91C72EEA6653EE2410D4A9A6E3C3E8D73EC6E26CDDB193CB93A773F9925FE1BB7379328A71DB0330DCEF9D5EDD75BF5E141366085E4DA600C5C07FC2B088A18F2216DC95200302B3DCFFA711474D8B8F1B6A1826B053872AFAE3E57D35C5E4E79ADE2E5AD0F4062B6F0414C4A62B003C3BE40661A68C20845B24A8F36A21EB453738F3C8337D975ADA8975B9EBC33188CB614772A +ct = 85639F64D077EA6B41149591F3938AD12E426318AF84E5A37C1F4F06ED25399F8E0B5DFB9E2F2339A5BE9DA8EAB6AFDE061882E24B92817BBFC7DBC3A7861014E4CA6333830DAF2F0A370870D901A48BB5539D54D4352295334742AE0A267306B6B9691C698512494F18C082BDD55377875EF5A69A4CD9F259274DBB3B1A25BD625131AB4C84B9A73AB8B2EB5047E3AB5BEA65E74B488B788B4EC70DF3F73384ED1815E0F7F92DF6084B3B53BC3F27DEFCED64C518823FDB00D4A60D36EEFCDEA8D3C39F527256ED390D0C3C06ABDE7E1D57B16F028DD79F62D92E4E7177C83A81E9ACD231F53B4746B85B470D063512EE800BACE4D9DAD29221383090B86E4DFE811784D1CC08E91D6D4AEB23FD8C3100A1EB76CA4925F25A7352F71867BA829E19D8321FC1A9754B3AB6CD451653DA30BA80E14B982B7C55F3171DBDAE3EF646AA091D5AD078FD8B70E14C4ABF18CBFBB289B56B7D41297BF800DEBD2F8414988F1B07A533F6A8FC19525E8E7592D46D4B31E592B687571E086E88E84C11A94040B5376F89C32BC6E2F9FCC123D0FDDC80 +ss = 0F6EB990A39CE2345A3D3340ED763CD0C37CA2D21C13999C + +count = 74 +seed = DEB963F8B1D8FBDF499D564BA8D2D47915BB402DA02F17031B37B4039A842AFB9B7E48F37200605992BD2429427A7A4E +pk = CC8CE6FF50B23579F7400E2D0889EB8455276FA195F9708F1F74ABBD978FB707D41D100FA241B29346D6D3D048F0348A8E0AC825CBBA139173920F4C70A803501DB25E43E9FB0AE625791B400FEF61338BB402DA2E3205B15F7A798DF5FB856C3C3F5A04F5F729494DB41884861D0036A8CF6E32269C646754B8113E501F4DC9FEAC0D284C805628E0462FF634CC1B291DE2D3C1B5D10100FDF8FFFE9240C1C5BB61CB927E0FDCA9460039A8F7E28D2F81D1304A55165F0FAEE0066A1897AF29469A2E376F6D520435D3068E5CB9BE4645194E22B83D94371DD2B4CB4D1B949CF8D699B4A0BF55C8631D79F41181CA0A88B2211AAC04BE1D96ABBE0DB10DC1E1A16D9DBF600C7E22999CD65AE6CCA052A1C6B3EE68E114BDEF3BF5D8622FA5162423C38493FE0E6E9F5A20F4B90DAAC2A63053C1466B26C7E415002B31880B2E65375402FE9F81E645DFF1CAF5CAF8DFB9077E6A69DB1798DFD730A44D924C4CDBBC0C52D3CF179A6B53148555F00609C6606F6B51B4665A1924 +sk = AE0F65E29F38804A6759F70F4D01E2AAFF7FE1C91EBC4F89E03FF73E02A217659F53D8C47556BF3D8C94040F630D63605E2D0F923579370CCC8CE6FF50B23579F7400E2D0889EB8455276FA195F9708F1F74ABBD978FB707D41D100FA241B29346D6D3D048F0348A8E0AC825CBBA139173920F4C70A803501DB25E43E9FB0AE625791B400FEF61338BB402DA2E3205B15F7A798DF5FB856C3C3F5A04F5F729494DB41884861D0036A8CF6E32269C646754B8113E501F4DC9FEAC0D284C805628E0462FF634CC1B291DE2D3C1B5D10100FDF8FFFE9240C1C5BB61CB927E0FDCA9460039A8F7E28D2F81D1304A55165F0FAEE0066A1897AF29469A2E376F6D520435D3068E5CB9BE4645194E22B83D94371DD2B4CB4D1B949CF8D699B4A0BF55C8631D79F41181CA0A88B2211AAC04BE1D96ABBE0DB10DC1E1A16D9DBF600C7E22999CD65AE6CCA052A1C6B3EE68E114BDEF3BF5D8622FA5162423C38493FE0E6E9F5A20F4B90DAAC2A63053C1466B26C7E415002B31880B2E65375402FE9F81E645DFF1CAF5CAF8DFB9077E6A69DB1798DFD730A44D924C4CDBBC0C52D3CF179A6B53148555F00609C6606F6B51B4665A1924 +ct = 7C8AB30D6F3D0C6C3B932C50512DEFA808913A59C10F68740BD743A6BED7509CAE3D6440030B10B85DC762FB0EB432867202FCDD481F89DBEEF919B0C8B73F086F86A666CC8437529694A5C18E902BCCE8EDA0D30BEDB812E72425D5B098D10722BB492BB5474E9187764C963E4BFC6CEB578182BB84B94275B268D18B218B1DBF000E3C9BEA622BF763913E18BF87843DB707D0DCF1FEF46C8A8FABB218E3EC79A9FD99420696152C648EA50F59E3D4C4C607DDA503E20A5451535D2CF234CDB4D486DCFCFA31808AE1A516BCEE9B90D7E1F2A269DCE171547B3516BFF3FE1DA415DEB901FCE47A174FCAE8B155C00D41DF2CE4E833C2E0A684D3372A0CCF1EBD9EC00731A992A4132A397BB3D4B695518EA32C41FD17E19980B17484DEA217722EBD53CB0D05C3C33292EF96ED1AD09B3DB0FF26409B5B235F2E1D6A8BD9B0BA16FBDA285EEC04F08A90985913BA620B949CE42957A084505FBEC588D2A811EBB87FB038DF1D5CED67378AFF21876538FC7148620D3AA136080AFEA98E86A27AC772E63E16F48AE88D9714039B7EA26FDD +ss = 9A0CE5F63E14A51EE73FC499B06CAD8C065CBD2CCF52E806 + +count = 75 +seed = 8E2995F1B3E43853B18916BB1212ACEB05898E2B177A87ABEB928AD7184E59695C56B2CCCF5DB80853C28A525E327D13 +pk = 755B3457E6DDA5D8160164998FF89B47CA3E3C6A94ED094FFB149B1A6B0EFAAB67442B626F12AFF10F140815D54AA0A8D6AF98C0FB0012E38467D4C0B50D183E84CC27ED568F85DA4FCB3F3832B200E6F1DECB9D61C2A3CD756DBFA0940439669DFCC44066FE3A096FCDBFD5611129234E8DC7838B6B6794F3E8765E69200AA5239C0148515DF6DF989B47116099CC5F80D725B1B2EB3E9740EA7D9E736F100931B598FADFF1632ECF8209C9CEFDB998DA7B0F1CB1079BA00346912A060029086AE46A41029688C35C5057773A0D021782519F01338A89C1A83228F29679C5A7D5769F1122A0F2B7C07401606082E4222453DB49C95E804A3CE8FE23D5F8D0DCFE7BDFE96D1AD076A3DD1DD4F68969A7B3DA491FA958FB7F8DE91312FC104D04D5705C3A5723826755CD06AE5EAB71551D8D718D22740A6E3C2D0C4E1B50618A59A3C07982E5C46F67ED190B2CE402402ACA39C988F8A52ECC82B590796D3B56133ECF1FBA752DDA1765BF5957000033C3C443D1319E39D8210A +sk = 6084A235F79DD093EF6D185B54E69DF33DACEE73A9BF2F379F684FB055ECE19459EB464E91E126A7A6E3ED11CCEE0046DA234D964C985100755B3457E6DDA5D8160164998FF89B47CA3E3C6A94ED094FFB149B1A6B0EFAAB67442B626F12AFF10F140815D54AA0A8D6AF98C0FB0012E38467D4C0B50D183E84CC27ED568F85DA4FCB3F3832B200E6F1DECB9D61C2A3CD756DBFA0940439669DFCC44066FE3A096FCDBFD5611129234E8DC7838B6B6794F3E8765E69200AA5239C0148515DF6DF989B47116099CC5F80D725B1B2EB3E9740EA7D9E736F100931B598FADFF1632ECF8209C9CEFDB998DA7B0F1CB1079BA00346912A060029086AE46A41029688C35C5057773A0D021782519F01338A89C1A83228F29679C5A7D5769F1122A0F2B7C07401606082E4222453DB49C95E804A3CE8FE23D5F8D0DCFE7BDFE96D1AD076A3DD1DD4F68969A7B3DA491FA958FB7F8DE91312FC104D04D5705C3A5723826755CD06AE5EAB71551D8D718D22740A6E3C2D0C4E1B50618A59A3C07982E5C46F67ED190B2CE402402ACA39C988F8A52ECC82B590796D3B56133ECF1FBA752DDA1765BF5957000033C3C443D1319E39D8210A +ct = EDAD72D61F6AB163D9993D55082228DD46495C14B70FA41CFF4AB0D7142687E89FDC951FC0BEB9781ACECC15F8374BB86A75F4446A2A12FC60AD30C0C1B10446795EF1B3B95EA9010862F0A1027D7A0FECA5870F87D3C88AB1B813F9AF03F952882E2F152C7CD8B1959012415F885A2AD68BDF84258E16A0225DDC7DA438C7C39D2B56DC2A291BE156F6D66EBFD01CA940C18E827847A13164D098E9FDE43807A78EEB84AB81669F1647C8D6527601B7CEB1DDAFC9E4B2EC437895F9321EC845787E930FD891A1B5111A39915EF7274488137ECFE07EA9DF4D2A7A1185ED8037B2C6973623BD79F4F4F38A6DBA59B0961E38B47CE9C3CBFEE174E520B3918B323F50F003DB9A76C143B0FAEBA0EE395D8C53FF947876016E2906B4CAAECA44B44D35722D51CE63F2C76D83CEC671F4C6CCF0B22322952E2F86312D187F5C88B15A9426D1CC5E601A8942754AE4C0A981AFB72EFA9E9268A23AEE814FCC30C1639BBE6FF613F376834460B7976C10A10AFCA6A9B17F8F5DF803381CF5FDDF3FE54B21E7807B798181D80DA7D1C5D6EE80ED4F +ss = 3B2476445718E7F3D3B24A14337C1DE26F9612AAAD6E522E + +count = 76 +seed = 9218943C51FD2DE47E509AAC67EFF176795102F37D7A2017E3AFD768FCDA7877AF38739B00FCDF227C2FD62EB635942C +pk = 7AF1FC339562DBF5021CD0DFB674714657AE5922C43319722E50D3D5BB59622F2371B478F67731688BF2BE0966E1C66F74B507367FE099ED06FCEAB04DC90DB5692361243A7454F37A292BCADA77BC613AA929F371F0758FF51D58D55A79D1FB068F9CCD3ABC5DD076D3195B9C4F1C05B97DCAFC8C2C4C829D41A8D2FC10C1E69972DC43225460D7246E2F8B235B218F2088167FE2E25D9725FEC4DFAEC534AC821BA3690D2D66EAC21C2839F3F828CB82A61DC3DA9C3C1BA9EBF6F70BDA36D87A0F9F0415791A9B2A084A593F9A030AAFC3EABD4E564DBAB7DAA89D982586804BFDFFD6856E9235FFE44FDD81FA08490FA4248F0D35E2457986442D7BFED62514064E90CCE7ADF695A8ED066735E625D0BDCCADFBCA97DC1CF026FFE2FCF4B7C2D85E3DA9438839B71A9A9B7B8E21E0B9A012B1760BF897E5202820D8057C8A95377E3CEB8878A43367C1BC3EEC981A5A9019CB72599010DBF281DA74FFF2BA427487ED2B3B7DB9E125FD399A41F5F7246C8318156D59B49E0B +sk = ACD1C0217FAD5CAA4235544DD9DE153AB1880CCF4C76F16FF03A8ABB0A5010F400AE5722A75BDF5A2F6D5B546B34D73857CB1BFC7E587A077AF1FC339562DBF5021CD0DFB674714657AE5922C43319722E50D3D5BB59622F2371B478F67731688BF2BE0966E1C66F74B507367FE099ED06FCEAB04DC90DB5692361243A7454F37A292BCADA77BC613AA929F371F0758FF51D58D55A79D1FB068F9CCD3ABC5DD076D3195B9C4F1C05B97DCAFC8C2C4C829D41A8D2FC10C1E69972DC43225460D7246E2F8B235B218F2088167FE2E25D9725FEC4DFAEC534AC821BA3690D2D66EAC21C2839F3F828CB82A61DC3DA9C3C1BA9EBF6F70BDA36D87A0F9F0415791A9B2A084A593F9A030AAFC3EABD4E564DBAB7DAA89D982586804BFDFFD6856E9235FFE44FDD81FA08490FA4248F0D35E2457986442D7BFED62514064E90CCE7ADF695A8ED066735E625D0BDCCADFBCA97DC1CF026FFE2FCF4B7C2D85E3DA9438839B71A9A9B7B8E21E0B9A012B1760BF897E5202820D8057C8A95377E3CEB8878A43367C1BC3EEC981A5A9019CB72599010DBF281DA74FFF2BA427487ED2B3B7DB9E125FD399A41F5F7246C8318156D59B49E0B +ct = 4875B2B3582CE1B7D90D654131B043D8724A460D0922E1358CE269ED5779EA58F0BCE7AFE61BC976CEA31824BA77406E069274191B459393A7438DCC218D21997AE498D459D99C170927D9AB7B9551FF1D38D4994442EFE5A936E598FC7C953189C61DDAC976B35437E481EC0A43425257402814711882A5D4237BC2D70DFF42B0322117B91DCBB96D06DA1C0520462F0C41234C35DDA0BCA52C5882B01034CE5E8102A24B3924CB33C4C4C4697514DD4CC37050469F58A4510C6D493974BC39EB508B05AADD1DB502CB24CB8C26A9814D34F017378D1B251F65F959C6103E64CCA6FA099E19F483A0AEE036E44EE8AF76CC56B778E454BCD4063023ADFD840ED30AA835C051DBE8243A87CEE6595680576395194E78C05022C413489E808DD6A36743C3F6F83B9F3DDFC05A00B98DB6239C5D35A99A85E20F0C282789F6B3A5B9055C5AE312A0635EF0800250FBBC9A376DCD46B29F02313A8C90F8FAA8195A4E6079BA8AE876C18A9DB1CB00BF10935E9183EBD65A12A10840AA676C1F36C347B05505B9A316A920EFC3314A1D574D2BA7 +ss = A752CC792C587805D30F9FE4250155822492E10A93161E61 + +count = 77 +seed = 542E20078ADD5296050AF150360F057F6B9AB3BA835589DD56987DE805F900B906505B5390A0D86CBA28038992DFC59A +pk = F719DAC81F1F140FABD43474E31471E9F1732886FC66B4DA09B926E5727702E78CDA06384727EDBFA17D339336EF683ECC8DF3401350A81C0C038E60B56A3646DEDB4293AD1C824B09AC83F07EDCBF9E558A2993E1D59271415FFC56A6ED7A361454401AF0BB667B255BE7F9F855DFFCDF6A548AE06F326050D6D61B723F36493F0B6447D2C18465C8B62C53DC50C864CFB1728575CE6A6734CEA506169E0A3CB971432FEB96C961D829B8757D7C91D329E25FCB78EAF2DD723F070324E14F7072FFE03AF40B699B29F381066D8E5E7754AEFAE650ADC3A1A688B54B838DDAF34A3E9CB9E228DE2AC4ED45E279DB9097673F8B764424B5C617C5731CA3034E1F89D2E929BB46DA4B30F34668AC442FE71F4DCB8459408909BD5B6A6909710839DD4D4696EB73C87FA0DBD903C42D6ADA5E1FDCCCE49BCBF6AD48354DAF5268CF239BB5C854D90BD25B60AEBC57B330F42953DBBB402D957288E3259B69019B26976A60757F038DE317CB9B02478F48F3FB88A915B38201E3E839 +sk = 241191401A63AFA750F05662E354DDDBC683C776CE3222BEA59B3BD23B49A95BC1FAD20070FEC930B6060BD827D742B077092E422268E10DF719DAC81F1F140FABD43474E31471E9F1732886FC66B4DA09B926E5727702E78CDA06384727EDBFA17D339336EF683ECC8DF3401350A81C0C038E60B56A3646DEDB4293AD1C824B09AC83F07EDCBF9E558A2993E1D59271415FFC56A6ED7A361454401AF0BB667B255BE7F9F855DFFCDF6A548AE06F326050D6D61B723F36493F0B6447D2C18465C8B62C53DC50C864CFB1728575CE6A6734CEA506169E0A3CB971432FEB96C961D829B8757D7C91D329E25FCB78EAF2DD723F070324E14F7072FFE03AF40B699B29F381066D8E5E7754AEFAE650ADC3A1A688B54B838DDAF34A3E9CB9E228DE2AC4ED45E279DB9097673F8B764424B5C617C5731CA3034E1F89D2E929BB46DA4B30F34668AC442FE71F4DCB8459408909BD5B6A6909710839DD4D4696EB73C87FA0DBD903C42D6ADA5E1FDCCCE49BCBF6AD48354DAF5268CF239BB5C854D90BD25B60AEBC57B330F42953DBBB402D957288E3259B69019B26976A60757F038DE317CB9B02478F48F3FB88A915B38201E3E839 +ct = 09A679037AF951CBD5CB02601B1B67467DEC6FD98CA098FBCCF36C367D122D4D5AFAD6D18D30735F40EC22E56DE805D82ECD29DAC428D6E50837E94693962F0E59C27AC8165A4CF69B02DF9C6F37747D8D3DB6F07462A3E6E0E25B74F81B6A0A30BFD5EFC9FAEC652F1415CDCD650CF2A59E009239AD5D8E5B049281CC011970818C6265B9F47F1488B36FD0B0C1D63C594555961089C4EE89FD9B39501998E289597AA60D86A4810A34350B91EEDDD7405C0E0E67235A235378D6AE0AD3F455A790272062E916E66EDAEF46B6388C264980B15A8CF3C173EB73CA76437EE689983241CCC9D4A9BBBC8643602CCEF33AFF79F3180363072B722E2239C13723C2C763885C4B41C9C2ADB46AC708AD738F91C9D38470D975DEA1FE02A9CFB23106A95EFC740A8F6B42B7355769FA70E76B8F1AAF7E3CEC9E90BF180E8E05B9E8FDC218376271BA9BF93F19E2B5BB3C59A8415B7F9229A47405DC843F3EB93AFCB67B35126C99E0164EA02A68FFB2DA846A0A32253A21111DD4BF39FADD6BBC65EDCC8089EBF87AE07D81744F4962814F687302 +ss = 43C4B61F15FB7124ABA3F8E872901C308909310E67AB95D2 + +count = 78 +seed = 6A85A61DD08C0733FCBC158ABB49FE0B0D96A50DCCA140A2E9F5A254F1901985844613B1C656C0CB0112620591B88AD0 +pk = 90070817561E4DC82AF6056F74C3865A2F1A4D05B3C200434568A9492CF83E6008AE2157D98D3D8A66125F3D0402D1A71E6676527056067B216A206FE37E325DAE25083E3A5D87211919B2DC162A833FD71E0B0DF18773F814A89324139D2DD958D518E676EE009F2DB36171001069C32B0B892AEE0182A79C72C1C6AF3CABC789CCD6FE92CC8FE0DD3BEB586707B103950A7BCB89BB2896CA4E7626BFB700E2A6416B1EBA1655A2D590C7C24C3A42FE12676FCB48BD703C82ABBDD615CF5ED4241D6F15874705BD958257983D07E9B5AC6901A4DAE3B9DC245D84941D4D53E96D75E2CFD9F7C430238F61DA47E96A6BFFF4E78661DE1C750F2232400EEF8E7933C2C03C5AA072E1D8A2AB4FE30F6AF0722CC72E454A90779A53D45E7C49E46CF537FED39E02EEAA45B1E3EB6237BF3B818196B9CBCCDC6CF1F3153572153CF422DF7A7AEF3521E4183D4A8C824CA209E5EBBA8BF8FFFD16B311CF4ACF4CA601D7E19B1F043424F36EAE25C6003DB0DEB08932BE092C8E798C18 +sk = B9A6B0C05677E957D41A34BA03BD06F2A9092E31F6338939E99C0E7B82BE89BC3C1EAEE6680AA4EFD394E40C2B3F30523C8117F7C26A890990070817561E4DC82AF6056F74C3865A2F1A4D05B3C200434568A9492CF83E6008AE2157D98D3D8A66125F3D0402D1A71E6676527056067B216A206FE37E325DAE25083E3A5D87211919B2DC162A833FD71E0B0DF18773F814A89324139D2DD958D518E676EE009F2DB36171001069C32B0B892AEE0182A79C72C1C6AF3CABC789CCD6FE92CC8FE0DD3BEB586707B103950A7BCB89BB2896CA4E7626BFB700E2A6416B1EBA1655A2D590C7C24C3A42FE12676FCB48BD703C82ABBDD615CF5ED4241D6F15874705BD958257983D07E9B5AC6901A4DAE3B9DC245D84941D4D53E96D75E2CFD9F7C430238F61DA47E96A6BFFF4E78661DE1C750F2232400EEF8E7933C2C03C5AA072E1D8A2AB4FE30F6AF0722CC72E454A90779A53D45E7C49E46CF537FED39E02EEAA45B1E3EB6237BF3B818196B9CBCCDC6CF1F3153572153CF422DF7A7AEF3521E4183D4A8C824CA209E5EBBA8BF8FFFD16B311CF4ACF4CA601D7E19B1F043424F36EAE25C6003DB0DEB08932BE092C8E798C18 +ct = 41007EF2957266C353F81778BF4551CFD13D168AC4496CB62AE4277A71A23FCF664918DF1660781BAC13600B5B0F00908B123BCA9A98FE45BD67E2F4C2F020EA720EB5FE47A7461BB8A8676D045CCEDA9EAB2E62A99FC05D1B1EF504A851987031302C2B9E72A80ADD65865FA2F4DB9A210B9BD5DBFFF3CF55B465E8D5278CD0EC5EC59E291A40EAB4503D7718B0DF744092BFD5AD2042CD4B95F73CAA9A7FD4A1FC92E6BD8FD05C83F377A5821B40FF64CBB91CF5B6F3C40CC4EA653AA3554CE08A6A0D3B99C3A67DD86F177792E6E1606F50CB8A23CDEDD5190B6235131B2175E06CB2FF38953EB51A92E48F0D7676E4CF940FA341998A7210011763CC457F9B5C25990B55548B3755895FF0F7CC52C668D580AA19024F0677746C798E9127BC6E165B1FCCC486B0D30B46544C2F32A119CE2EE8A0FD9D367C1D8981F2C973D9AA427B31F5F764F5D0148DA72C8AC3AB820FFF835F2DBCB38CE5BD6E3A8DEC7DD0E372F8E18044C57B34FB240644251F60A30A792E8CD54131A49C9B2491BBC1EE688453E9CE95E0C3CD629C82F3302BFD +ss = 0B6B8EC0C8CFB0ED111785D7CBDE0162A44C96D58772E5C8 + +count = 79 +seed = 7F4A56EDA151E7B097CFB8EF980440FFF707AFFBA91867C89522CED6C5FF3BD7F5F00BB49DDD615D9361A7E4EFA42851 +pk = AFF975A50503593502668407B35538D635D667510EFE5223D9BF5C25E9CF90497F49E4B42C5129CF7B00EB08A9D41A2786134332C78B543A896600C95BFE1B661F9FF6BA4E3FB208023579B310EED4484B045D934DF426DC6D20C3ECA1CF97C994B70F2DFD251B232E44B651440EC50537CFB57ADCCB39B298B21972620984524D350799B1AC0B9C3DACC0993E5D247DC8ECF1348073E8C7535EFE765EB091E791DE42BD42C4F83B1294C252575BDCEA928BED00D8BC214E86E6A135022E1702B5523B35A68862BA25D6CE3877950030EF989CAFDBFECD23FBC329DD51B290C53CEC4049C511D0027A4EB9FE77C8CD298BE4F309C8B34A603F5A03221A955E1F976B034EA4F827E1D2FC1A4F40C7FDDF3F73236135BA565949129B2E4555EFB497CB5BC8CA3851878BBACD6584F59C63FAF4A0E18EA8C7CFA95D1EEB4E73FEEFA9A85743BA8CC291F68C1B94EB19DB928CDCDF353136ACADCD03DCD4A2F888A3426884F9C3C5C4AAD4DE1A9F53D22407BDF57633D97B98DCD108 +sk = 28A96C71577BA00C94F99FE965BC595A26DB2B3CA6AB5CF89C35D165453E5FCDC6F9DF64526D9DE698F2BD3E6BAC6C7FDD86601B9BA5F405AFF975A50503593502668407B35538D635D667510EFE5223D9BF5C25E9CF90497F49E4B42C5129CF7B00EB08A9D41A2786134332C78B543A896600C95BFE1B661F9FF6BA4E3FB208023579B310EED4484B045D934DF426DC6D20C3ECA1CF97C994B70F2DFD251B232E44B651440EC50537CFB57ADCCB39B298B21972620984524D350799B1AC0B9C3DACC0993E5D247DC8ECF1348073E8C7535EFE765EB091E791DE42BD42C4F83B1294C252575BDCEA928BED00D8BC214E86E6A135022E1702B5523B35A68862BA25D6CE3877950030EF989CAFDBFECD23FBC329DD51B290C53CEC4049C511D0027A4EB9FE77C8CD298BE4F309C8B34A603F5A03221A955E1F976B034EA4F827E1D2FC1A4F40C7FDDF3F73236135BA565949129B2E4555EFB497CB5BC8CA3851878BBACD6584F59C63FAF4A0E18EA8C7CFA95D1EEB4E73FEEFA9A85743BA8CC291F68C1B94EB19DB928CDCDF353136ACADCD03DCD4A2F888A3426884F9C3C5C4AAD4DE1A9F53D22407BDF57633D97B98DCD108 +ct = 2C6F1C997D00EE31E35DD4A45BE079AB61CB0EBB6DA09B31E3DCBF45833A29774711DFAD2EC8488E992236D22BE1BA98E983E9447EF45342D1E0D852BD65009273E2CDFDD8F82C78F6798AE8D194FA10701C53505375C16D8A15C51FB996BF3503090A83374A3EAF9C65323E8C146CAECBF71B1AE623F836540192141101189D71F9F5F5566B2DCC3C629481654F6C897F18ADE97C442715FEB67270434F483FBE43AC98DB0C95C741CD279ADE91F2B5C552E00231ECF9C24EE5CE442A3555259FF0CAB25496B3B43162C826CB4249102F808A568D6E3B804D21AD2222B25F034989DFC9C4D78487A6F2A513A12DA15FF46124577AC3DA408178F322BE51F89869135E21804BC6C3C5DA9FB14B1D6324234A5D666AC9418FD639D703F908D43826C54A8CDE4A79051066B4C0CEBBD3F0B22B1CAD29053D213EC92A918CCE8EC29C9F1478FAAEA2CB5B83B20BEF8DA51C101FD9AC66478A6F92E5D034E260521D750F3CBA3481232EF8625DFD18DA8992DA977F67B5D05E354D3B9853F5C23BA2BE3B93392865B5A440BADF3F456C78383B55 +ss = C506F215F739D554DA46B2C9FA8F98DA69B52E1FE7BC5574 + +count = 80 +seed = 09FC004519BCF85B20D25D314A0DFC79E00CB6262A7DDDF9C52473641AFB8CFA0F5DD5F53558184CAAE9EC34B459E98E +pk = 65B3C48E425334FF990E508E62646CDF7438BAA837C610B4221965DADF5CA7717533376C91EBCFF3A057623DE4594A577F12E24B3200E04758BB2BEF56D61D29376AD9C8763AF9CED27635130D62ED4CCAD330F476DED5540F4BB1F38A61F00496467CD9A8FA6FC1E2F4B251B932F5A0153945FCDB0723726E9A0D4AD02379D730AC17B946C2DFF3E672B4058B1D1D7D555C22C2B971761C180350366890C87C8EA8BFDD5EB2D32807CD6FAE148E76D6180AC0650FBEA4750E8263A935405B3EAEBBF7E20479F7790BFE875AAFA7DA2C882BBEA0966E7932900DF093EA372F49B3CDB23645BC2689F5D1E133DDF6F9C10E317BA919C85FA9764C163F98E74F4DA4614740FE3BE298ABB600772DCE67F0CF6C8FB2DAC1D642A77796549AAB51A42C800413BD05BE5A8EF3AE980A80E112ADE5D48287BF8608ED9E2813573CC4572EC12253CED927A7BD9D54CC0343A8E2693613770CA797D1B2A0914EEC34BE8500C51BFD1C7AB957C4F8463F993432BC69C60781F9475BA1AA3F +sk = C08BA2EF8C3A0A043AFAD931652D7A19E6E8CB670F840DE55FE6141A25F7AB9F875F79E0A82D6EA5CDE5A017AB637D5FDB7C42646A1D710F65B3C48E425334FF990E508E62646CDF7438BAA837C610B4221965DADF5CA7717533376C91EBCFF3A057623DE4594A577F12E24B3200E04758BB2BEF56D61D29376AD9C8763AF9CED27635130D62ED4CCAD330F476DED5540F4BB1F38A61F00496467CD9A8FA6FC1E2F4B251B932F5A0153945FCDB0723726E9A0D4AD02379D730AC17B946C2DFF3E672B4058B1D1D7D555C22C2B971761C180350366890C87C8EA8BFDD5EB2D32807CD6FAE148E76D6180AC0650FBEA4750E8263A935405B3EAEBBF7E20479F7790BFE875AAFA7DA2C882BBEA0966E7932900DF093EA372F49B3CDB23645BC2689F5D1E133DDF6F9C10E317BA919C85FA9764C163F98E74F4DA4614740FE3BE298ABB600772DCE67F0CF6C8FB2DAC1D642A77796549AAB51A42C800413BD05BE5A8EF3AE980A80E112ADE5D48287BF8608ED9E2813573CC4572EC12253CED927A7BD9D54CC0343A8E2693613770CA797D1B2A0914EEC34BE8500C51BFD1C7AB957C4F8463F993432BC69C60781F9475BA1AA3F +ct = 10A444F2EFC022C5B6AF04AB20FF9F101B7437C20A7902B53E321BC52752008C8CDC6F43BFEF35BAFFB17013F838387B4CB528BE5B9F4825CF868804416D2AE917E0208EAFC78844CC4D5E15D425016B390E27ABBEED26398E2EB1EF7FAEF2515F9067216B2CD92D95A84B34CC26714013844A4A6F169921FBC4EF9CD21CD9936F089616CF74E288DE1C9958DD4BF593C3EFAE0A0FFEE8573D875E04611714AEBA9D526602EB06C4B2E5083E6565F6358E64FCC9B2316D948F5FF9232BB86A039D0F350077AA9411C08D5C99544CCDB6C1EC4DF37989D5933FDB59E7BDDA4C5E02B579553F860C918BB74D3D1785B91AA027F100F60AC42165D5B222FC6EEE2DDAC579AEAAA7C05658D4CC929414C673387C95806DD0A6A626CE1F99BFCB20C1CCDB0F5A91A8015627D98ADAF8A07EF18F0F26507CCA29A5C2B53015CF3A807CBE09609C147DB4C6209449B3EA8E69D493E120942092C3DD5FEB6752C6C10CA2D80D6A3732FEC5CB2618D182CE665643095016EFC3393A066408D227C14B548A611BE12021E61CAA39FBAF695B0D84679AE0 +ss = 8E29194E92798F63A56372A284CBA20051D66FCE75098C33 + +count = 81 +seed = E3C41CCA6F04CFE7732FD54DE30CC5CAAC93E2F80E76AED7D24A962A3969C1B6A311459A3EC3E510E3E9B1E4291D4D7D +pk = 2B9A9445EAACDABD31AD55C16D217142CDC68DB45F519256547C4D969953059328AEF6EB5456C73674160B154F62DBE5F49185C5716F3A024DE4EBEA756F23729F8227EB42382B53B49AE72CD11F7C4CDC286DC6AF0A0BD2C1ABB58C373E661ACDD5F036F67C463361763D54A7E07AE3CA8F2D82D13B353A695FB617E005184090E413245382B6CDD3BE109B378828C7EC637552A88912127312ED7A453797D4E2971C116CC628C48337F5048B440DC32CE6E5EAB668A0CFDBC8BC3936DEE9C5281C9EE7F77F191525899D4C77CE15C3005914170D8AF1521E8C6DA8A6A2A07CDD0AFB9B989076AD0535E552020B19A8C4D148E5408BC2E61B69B93B332E1F37DFF246C98A2ACED92953376E00945B439A5389DDD18CFD8683E3FE16A2B671CB7BA206ED9EE26617B735B84757825E3D2AFE47C2AAA6128C47810883D98D6BB3F84F0603F6417EDEA1FB2C3268FD340CDDB2486487BE55AE154B83C505DB1A10549E3AAF24F8ED3E6184A81580D56D156E3381FEF2D3BF62DE04 +sk = 0E3B30E102D707538C2671060F603BB0B8A014103F132D6311EAFECA9E810796C34E8CFCE9D59342884456007B01DDD12EDCE6D10ED87E0C2B9A9445EAACDABD31AD55C16D217142CDC68DB45F519256547C4D969953059328AEF6EB5456C73674160B154F62DBE5F49185C5716F3A024DE4EBEA756F23729F8227EB42382B53B49AE72CD11F7C4CDC286DC6AF0A0BD2C1ABB58C373E661ACDD5F036F67C463361763D54A7E07AE3CA8F2D82D13B353A695FB617E005184090E413245382B6CDD3BE109B378828C7EC637552A88912127312ED7A453797D4E2971C116CC628C48337F5048B440DC32CE6E5EAB668A0CFDBC8BC3936DEE9C5281C9EE7F77F191525899D4C77CE15C3005914170D8AF1521E8C6DA8A6A2A07CDD0AFB9B989076AD0535E552020B19A8C4D148E5408BC2E61B69B93B332E1F37DFF246C98A2ACED92953376E00945B439A5389DDD18CFD8683E3FE16A2B671CB7BA206ED9EE26617B735B84757825E3D2AFE47C2AAA6128C47810883D98D6BB3F84F0603F6417EDEA1FB2C3268FD340CDDB2486487BE55AE154B83C505DB1A10549E3AAF24F8ED3E6184A81580D56D156E3381FEF2D3BF62DE04 +ct = DF8E3FC504DCA4D54090C43E75EF7FD0682DB3844D270838E40F14955294BFE9ACFC4D228A9650998E9C23E8E6294FDACA7327F173F6485F7F485AE6F8C7085B4391F37883D095A459BB6440C97D80AC9E0D4357B334366177F35DA3B72CCD9DBBA28FBD4A9183281A32862A7195A3B86E727A02BD21E7C3F457E431A735FAFA56D41EDA65CFB2EFCC0CD6739E013521E4368C60040D213D890A438F91D45436B228BF9291E4FFBD78CD94F47BE2A0292C41895707BBABEE6C97401D13628AE2E03BD24CAB7A3B0669155D45F3488A8E30377C86922014206D80F8BB26F136080369F3F72144BF4C575862083CE3004694B4011F8765209E06F07B3A9A42EA45E5B809E6E6F9606E96A140BFBB8D1BB6D053559C4D347C57E26E5E8F46186641043B1737E0A8434F86995B677FDA3E84279F8446EA85D6F560890FFAA07192FA971110DEF76D1436D2167EA51B4ACCE34B6AA620479DD9CCBB1FB73F33BD4A872E0C4723449EC29DC9933DF5FBB1851309C1DF618050FEF6790442113455094FAA5FDC1B586958B4F9171F0923EBFA5907E8 +ss = 78B38CCB78A36C6AC719A53A4A571DF65F7021AC114D0742 + +count = 82 +seed = 373FDDE922CFC416ED96B444E445BDD0962E8989F6C50ADF9912A89937C57217D3600B06C95440448E3F601AE69CA5BE +pk = 1C7E2A130909B77F803593A301FB85090C230E13ECC2EE78E334D2430966C97AD9A247D26E60FF6829C322D0EAB81BE002F68FD58AF1C0C75178AFB5572C374A30AE2674604EADB98A557EFA4A0C5F90AD82078CCDE7AE7114BFFD35ED119696AB6033743DDE087876F8AD4D1D187D95B3D1EF8E9A01ACB133B4EF99E40AF2A09A9EAE85E4808FAE59D480A62DC6CC001DC76F15AC8AD4BAD5086FDE9D3820D9FBEA677698967CC8BC976721AE75E25F884467CC866682B13A5CD0A9028A57B01D8831F44371F4798843780C2505EF1BBF8FC6DD0F44ED368DB04A10E6EA9ACA0B49B14F36462ED85C672BCE50E226E3EC6645F010B31382D2953A2955572550812AA2F33EF7947DC6D6E9DE6B2442DD369D774DDE284F1D9BF4BA9B9E3BEDB71308D8CE787740E5F8E77E5C2D4839117E2963A8CFC8C49648850E2A1EBE15551650D8235A50BB5242F737D8E8F79FD184EA043275F3D0842E4537D86B451D6829E7EACDA32A343AB5238A0C086275C39093F23E6F06CF651822 +sk = 2478F7D3DE6041E7E5CD11C5E2EF483D1AA6218EB126444011136E2681DF2EF881B51A092A9BADBE72C9772C169808521C47149578621E081C7E2A130909B77F803593A301FB85090C230E13ECC2EE78E334D2430966C97AD9A247D26E60FF6829C322D0EAB81BE002F68FD58AF1C0C75178AFB5572C374A30AE2674604EADB98A557EFA4A0C5F90AD82078CCDE7AE7114BFFD35ED119696AB6033743DDE087876F8AD4D1D187D95B3D1EF8E9A01ACB133B4EF99E40AF2A09A9EAE85E4808FAE59D480A62DC6CC001DC76F15AC8AD4BAD5086FDE9D3820D9FBEA677698967CC8BC976721AE75E25F884467CC866682B13A5CD0A9028A57B01D8831F44371F4798843780C2505EF1BBF8FC6DD0F44ED368DB04A10E6EA9ACA0B49B14F36462ED85C672BCE50E226E3EC6645F010B31382D2953A2955572550812AA2F33EF7947DC6D6E9DE6B2442DD369D774DDE284F1D9BF4BA9B9E3BEDB71308D8CE787740E5F8E77E5C2D4839117E2963A8CFC8C49648850E2A1EBE15551650D8235A50BB5242F737D8E8F79FD184EA043275F3D0842E4537D86B451D6829E7EACDA32A343AB5238A0C086275C39093F23E6F06CF651822 +ct = CEDFF65BDAF1BF8F2A851BCA4264456480C04173C33C78F465D96944FB841137F7217D484F9C20FA1E60961741FC31F9CE128D64A63DA348E6172EB93468038ECDC91013474B53E179B0EE53D4884FA46263FDE4D400967F924265323B8B3452CFF0514F45EAD5E5BBAAADDF9E4409287C33448BD4028AC083A94CF21C0B65D9FF52295994C4A8215C4894E7BE275ACE0D8990EEB4263F0C6EBDFC3D2CBFC88EC8F6189073927DC4926E8183D75FCEF2783EFF90D7ACF41FD171F9F505AC19A4050EFA3961F3B0F276DA88E9E2EBC8FD6F72212535BF2643E51C6CBC37506B2D71677298CFE9F1DB9E996472496A06F3DB1726EA1D513915CA7849044281320A11DAD0D4E34DEF004E6E3FFDF5C7BC9F887DF9D5139058AD6927839447A7F78E8AC093527018479D8CB1C340BDEBE7EC3BFE313780E6395570BC086084518D305A2F2164A0432E9055783C9EB83DCEC4F3A9D07E8DD9232F466CD534D4B1F7688360B94868263B57773114C9AD0F94FA5242448F99B956C19E3B0F44560417A090139B00688DDCFBD2C7854B949D19F7B8E4 +ss = ED9343F159A608F60E3990C496282C01BBF5E6D1E5582C5D + +count = 83 +seed = 16BEF67F7AC3A755C59C816478B75FCC16CE5844DB537791ACCD1EBD49D2824B105FD2E970F728C8F0CF16E439A9AE2F +pk = 6C9B4D10DFB63EA98D6C89B8C03E969D11A5C764E25A01C952A304530CC58CE0216B09D2AC98F2DF4837EDD028BCD1BB3FDF2D2E033F1A333D52B200007B2DF201C71B1FA6B0DA29C7BCBF9AFD6A3E918BDC76122936041458257BED2383C8646A6B44D8B47E4FC2671C4745D4940D94D797D9D7A1A2683BB13D46064D00D458C927E6562A263DE32C07984411D50658F125A5153F2CA9D85F10BA4FB71123DF5669913D2F40C8E5DD67CC5EA2F96B1A138D9D860FECE2ED479F3DC03F1EB14A87347F5122245CD8587442BC0FB15D514E083487AE1F1177857A30C67F12996DD22511CE1848F10C17FA6FD3BA67E78F17C647889A55EBC7F9509D23A89E7D06CFA009BCBAE53BE32AFAF6606E56E2FC699DEF55EA5EC3F038A9F5305374698F2AD822B521147A40F78B2A5049494467EC77224073409E79A19F3DAF98FC285FF9FA6DB77C6F59A4F94ED206AF00E9DC5B7B329FD047820CDF8D174C785236C40F7849640A829E4CBC09910289F5CC12076286A1E819A05A3C22 +sk = 9D405D3EBDAF35FA8722DE431B669722ACAAEA2FD10B81436CEB14F7662BE0C42779459F69A145C0E2CE9F0BD9A0CD1BF32ED5694CC9AE026C9B4D10DFB63EA98D6C89B8C03E969D11A5C764E25A01C952A304530CC58CE0216B09D2AC98F2DF4837EDD028BCD1BB3FDF2D2E033F1A333D52B200007B2DF201C71B1FA6B0DA29C7BCBF9AFD6A3E918BDC76122936041458257BED2383C8646A6B44D8B47E4FC2671C4745D4940D94D797D9D7A1A2683BB13D46064D00D458C927E6562A263DE32C07984411D50658F125A5153F2CA9D85F10BA4FB71123DF5669913D2F40C8E5DD67CC5EA2F96B1A138D9D860FECE2ED479F3DC03F1EB14A87347F5122245CD8587442BC0FB15D514E083487AE1F1177857A30C67F12996DD22511CE1848F10C17FA6FD3BA67E78F17C647889A55EBC7F9509D23A89E7D06CFA009BCBAE53BE32AFAF6606E56E2FC699DEF55EA5EC3F038A9F5305374698F2AD822B521147A40F78B2A5049494467EC77224073409E79A19F3DAF98FC285FF9FA6DB77C6F59A4F94ED206AF00E9DC5B7B329FD047820CDF8D174C785236C40F7849640A829E4CBC09910289F5CC12076286A1E819A05A3C22 +ct = B68697EB5B2F8254C3E020978D86697409B30069BF60B136E27FC738A833776F4D95E0E24CC7AA3620AA5697062C06FB4671EF14836A23C708BC5BDAB05F24B30D735E5AB63C647BBCF235F25B2834D9612753C71F508C56DC4E57636928FDD310B113F7D4A14B0944BD8D66457CFB3AB6BC214DBAB89D30FD4E8966632B9F6CA3E04B731E20A19674573CF30700E50097EF9CE41D19BAABD878CA75EA8456FBF0F6B09F4A9704D3302AAE8BD4C232D18D3EB351CBD1670CB68771EE2A06044993539C4E72A18C86B7CFB160D411AE4DEE84F91F4D0D47AD5736A801149563F39A2FEA8C33D0EEE919B8408AECC9AD274B0A05848C48C24004180716D73BDC2B7CFFE1BFC9BEBB6C5C196EEAB37419E18EB58B0E7C107272B30890BADE2DF73057C60CD1FF5E3BAE8EFA63E2D1BB546318F3D518643B82164FFD2DA790170660FE3C31E0C3310F0AD0174F6012505C2E6F28CDF204441052631D9C6A469D6BB0EE08D509B375A439D32D9FB002D83A709F78B5EE73F299AAEF1A33CAFB01CA80322099E04E9628EEA2AF68A8F3BA8E9B5998 +ss = 37BBC45B6B83CDB5B8E1E01B05C8DCCA445E9362D853C869 + +count = 84 +seed = D0611F9AE5BE4DA5D7EADC9109944348E716CB3DAEE545721EEA8C892E7831CF2E54603146454CBFD92387739E9A78D8 +pk = 9D7481515ACA6FB379ED8BF0D31CEBA3E668543DDDD371E6622770CCFCD14556A93144B372F642D2814C66AE4A556E1319F0DDA9820D54B09D80022A74590EC9161D4F1797418764A34BDD587360490BBB0845D13033DAAD7615CFA84C186DEF1FF29A0BD8A81EF32AE108B136F5A2805E44C2F48C736FFF5A546C8D4501E283C162ECB7C7F667A8AD2F790216071B26BBA89A0F966A4674CC3A300D3CBD24327E9A57469D892B54D40A80D50B307B0139546D57C34C74B2EA616843314D9D9B178BD52AE2574BE284C4DE79DB6679E91A870F8D0FD4B97D946774EADE0F771BC315F9D58A0F6A1BB2F9FA0A960FC93A55B85BFB869C36D2AD14EE2AC57EEBAFC1C917602D6A4C9D60E0C0D540E0FF0BB503F913BE8472C035EDEC96AB2152908732977B18814FACF17FFCB7BFF29A4D44973E4FF32C2834D7791019B9E42A384A74AD7BF1E185D78E791E91432F0CB7128CF829B3D7808C95EF76BCD94A945685ACB1ACCCB1A6C7A606D68CD6E76E61B3326CDB5F75EAB1F501 +sk = 9A86490F0615F3EDF789CB0654066E9EE339CC59F968281FFAEB2EF44D2F608621E831187CE79B2D2F4A20F1568BBE76B0D3D5AF361117049D7481515ACA6FB379ED8BF0D31CEBA3E668543DDDD371E6622770CCFCD14556A93144B372F642D2814C66AE4A556E1319F0DDA9820D54B09D80022A74590EC9161D4F1797418764A34BDD587360490BBB0845D13033DAAD7615CFA84C186DEF1FF29A0BD8A81EF32AE108B136F5A2805E44C2F48C736FFF5A546C8D4501E283C162ECB7C7F667A8AD2F790216071B26BBA89A0F966A4674CC3A300D3CBD24327E9A57469D892B54D40A80D50B307B0139546D57C34C74B2EA616843314D9D9B178BD52AE2574BE284C4DE79DB6679E91A870F8D0FD4B97D946774EADE0F771BC315F9D58A0F6A1BB2F9FA0A960FC93A55B85BFB869C36D2AD14EE2AC57EEBAFC1C917602D6A4C9D60E0C0D540E0FF0BB503F913BE8472C035EDEC96AB2152908732977B18814FACF17FFCB7BFF29A4D44973E4FF32C2834D7791019B9E42A384A74AD7BF1E185D78E791E91432F0CB7128CF829B3D7808C95EF76BCD94A945685ACB1ACCCB1A6C7A606D68CD6E76E61B3326CDB5F75EAB1F501 +ct = ECD64FEC7DE41222060198881E2287F8A973DA1A64A4D3076FA406978D19A03089AA74C7623D50F568D540ED3A058793D5A092BF4426E6C2833815EEE0232F4C1900CE56391ED93357159DE5D4EE0D2CB25D91EB0DA1C82F743BB3C12DC35DD0419D953A0CF86566F6ABB081CCF302746EC8190D070455AE6F9D47C77907E1342F3C9307A6E93A6A36445ACE9AE66675D8C8E10B5E077E76CA38DCDA8546D7C036C081FD02C550AAF3DFC4DEC109470BC6C0126B1F0615BDB3E237403DA9907906C7BA8CE35CCF262E4FEDF6076D0E5F7B127EA7A25180F16E72A066B916AAC973A3670ADD0C34FB88A2CED9F99F940C89668A177D2FC2E9E7338225CEF4DB17822E57DE509CD74969200740AFFB1C7DB602CD680B0BC8ABB3803BBA044D4AE246F4247FAE9040C5DE2B9B23523FB1C1F1305008E92D8F9913A20CAC68E2CC2118DB5D0EB532E0D6A5D84A8CD10226FAA692BE6E07C6C7BA2063ABC3D1F8AA3B3F7AEF3E365CD44C571EBF8E205DAD0B47CD3AADF660A674E5124663A92318E0AB5972F2677DA8409DCACA621B5DFE4454C0 +ss = 93816F7FAE6511D47D153C04DD1AE13FF21FD701EC3B8839 + +count = 85 +seed = FBC38D7614D7718E931EDB850D2C6F0C5EEA9EE889B3E25BD69AC255D5B91E885D93E808E66BF9C88C655DC594DA5792 +pk = 243848C51898581160FF5A4F7C1A9EE24408CAE8004289892445CA11F8BBFF9011231C55A6C659913A39B9D7BB4E427554E4E52CCFA982153C6DDD1665352A0C8874FCF42C5896DC0AB029407C3BDF96D0BE6C7A70DB404E3F4AF8D23CADE2B1D809C8FFC17B4B70FCBB109002468C7F2D5F84E26D120FFA40162D4A95017BB9B5879961C7906BB703342EB6A58EEE1919E8A3AE3965EEC40D6BFF8D1FE260B45309EF2F6D4B9ABD181F04A11ACEF6FAADF3922C427B06BAA9F1AE770C6EB8F7890BD663D8B474BAFB866C7C03657DF4AF1C6965534653E4924B632A972DA493AA48A81A862ACE5715BB43814329302EDC0627EA11A5019141EB1F17927FB006C8EA0CF965B004CAB36FB22FD519E027A7B13426DC233E1A848A2D99F3D0260F34ECC063B253F0DF3E35C5D6F0CC7C0887957BB638B26A55CD20369474A42647BFD37A30BD1868C90A34D507D13C6A1F5E171A673134E67B6B1C1D189B931B3B3C8181F9710698733E2B99D4F58BFC884CDF6C7550E9CD08AD3B +sk = 6DFD9B575872560C7BDC2732C4A28DAC4DB04E535EB8E402A2985C1C4D203778597947D710DEC806E36B0CD949FE460EF141213BFC525E0B243848C51898581160FF5A4F7C1A9EE24408CAE8004289892445CA11F8BBFF9011231C55A6C659913A39B9D7BB4E427554E4E52CCFA982153C6DDD1665352A0C8874FCF42C5896DC0AB029407C3BDF96D0BE6C7A70DB404E3F4AF8D23CADE2B1D809C8FFC17B4B70FCBB109002468C7F2D5F84E26D120FFA40162D4A95017BB9B5879961C7906BB703342EB6A58EEE1919E8A3AE3965EEC40D6BFF8D1FE260B45309EF2F6D4B9ABD181F04A11ACEF6FAADF3922C427B06BAA9F1AE770C6EB8F7890BD663D8B474BAFB866C7C03657DF4AF1C6965534653E4924B632A972DA493AA48A81A862ACE5715BB43814329302EDC0627EA11A5019141EB1F17927FB006C8EA0CF965B004CAB36FB22FD519E027A7B13426DC233E1A848A2D99F3D0260F34ECC063B253F0DF3E35C5D6F0CC7C0887957BB638B26A55CD20369474A42647BFD37A30BD1868C90A34D507D13C6A1F5E171A673134E67B6B1C1D189B931B3B3C8181F9710698733E2B99D4F58BFC884CDF6C7550E9CD08AD3B +ct = C36C0543CE42D4E148768C6B70058A57520F255DBB361358E7F28423E2A4598201A905C0FF29224FA47C1464DF3634A4E20B47C2439197437ED751DE6360167A521906A938DE4A33D156873270585642A6BAED5FBB94EBC913DE0BD4B83816E619A50943E3842014D48AB01DD743CE57BC743B9A3273A409BE2619ECF615F155C23D71FDC2EA7B096FD8B0919AE45A6601E1F2AF572317ED93C288B5457BB2555E6925C8DAA7E2803FC3797A676F1C352A6D1AE1279C8AAF598FA0C92557BB20F1136D815CEDDDB282D6F194B54CED3591871BA72E38B4DC1B6899A8D0E29AD9A2C3435940C459386A1C4DCD2107C7BD9BB7DC76259896CA9E6D0D02B32F274908794AB6989911626306A8B1EFF04B527638599FFDF27E711043D8DC9C3FC54006F8C1AF1C0295C5F3FDA7713669B94E1E0EA565774AF0F3156612AB7E3B1825875D7891DFEA88F831E34932D9903743D21CE6E617F89F2A087B2256E57BB1AF339C6F51052BBB0642991DC0D495BEDA74D1EC68D029260F4C3204CE5C8DBAB020F13F44102D89ACA08F41CF53778F72B664 +ss = 32F85E3ABC134C88F5994A0C9EE049FE07AF4D7EE67F12C6 + +count = 86 +seed = 1722219CB5DB47374EB0AF0232C856A57F026F1CB09E5A5799F4C333DD422FF6A0A67C4DA502FAAE727FB2D45DAFCF35 +pk = 25FB2248663FAE9C8A7F9871753E337FB67A8F856B056FCA3FD2897BCF1DEF515D906073FAF3D3E75FA695CCFF55B7F114668AFF281EFDC2D489DCAB3F8219CCBE38E48609D1E96A1C1528CA582EA7C62D56CE9438AF19C60D7EB155FA3A47961253EFF7C9F846A773DD60B449461C52E3601D3BF4527E0FF4270B81562A0CC33872DE6B1B71C590A11C6687DF01805F59C3B74954189AB5256C2B28CD11FB28E2F4CFF7D25BE53E0F46CD5D080387E3156337FD9AC16E0364BC679C220514B31134279BF92229E998B0760B826F8443E1B2CEC5B0FEB6907977EEEEC92F67A78B25A9224D3932B7268569604D04EF332F17500C7DF354C901AE23161C114D7A443BB0979212797E7B5EF37D6C8B45BE740AAFB529324ADEE5F5CE27295F4E37142995AFE6BC67B17CC38537C9163D9331EF3256DA883A28BEFC24F4BF1352C770EC38C4DC62740F1EA64997A903108585CA3E7056C1C963272A404955806240D348E58A289DFB1CC62C37D81C610ED11161D3D3F9DB1FBFF929 +sk = 6FCA9F4E384D8418075CC064C70730801BDB8249899D456ACE7683F8A03D3CF04E46970FF7D6A12494AE12558346DFC8FD9370BF944A010225FB2248663FAE9C8A7F9871753E337FB67A8F856B056FCA3FD2897BCF1DEF515D906073FAF3D3E75FA695CCFF55B7F114668AFF281EFDC2D489DCAB3F8219CCBE38E48609D1E96A1C1528CA582EA7C62D56CE9438AF19C60D7EB155FA3A47961253EFF7C9F846A773DD60B449461C52E3601D3BF4527E0FF4270B81562A0CC33872DE6B1B71C590A11C6687DF01805F59C3B74954189AB5256C2B28CD11FB28E2F4CFF7D25BE53E0F46CD5D080387E3156337FD9AC16E0364BC679C220514B31134279BF92229E998B0760B826F8443E1B2CEC5B0FEB6907977EEEEC92F67A78B25A9224D3932B7268569604D04EF332F17500C7DF354C901AE23161C114D7A443BB0979212797E7B5EF37D6C8B45BE740AAFB529324ADEE5F5CE27295F4E37142995AFE6BC67B17CC38537C9163D9331EF3256DA883A28BEFC24F4BF1352C770EC38C4DC62740F1EA64997A903108585CA3E7056C1C963272A404955806240D348E58A289DFB1CC62C37D81C610ED11161D3D3F9DB1FBFF929 +ct = C5BC5D91572F9A7EB51CC1FD9CAC1154C691A147E70BB583CA70F4468E7A603F8039F8510F379C12379EC2C453C66F022397164BF3E26FA6B84AF3F2C66F382A37E334ECA020E4DDDA91FABB92311CAE2AFCC215EE9A6971F151A8EB22D27F990164DC37FCC27133BB681CA4DB8D80974B136F40EEDB8B8733BD7E084040689CD1E95F0051C101C76038538B2F307AC26C27A618198A0B9D2478D66F52C6DD8905407B07F128F216F9F2AEA22DD333F4E5ECCB99D83BB26959A38028389E4D0728F6D3691619F79F11BB483C66F01552DDD90C084CC4E6A0D9A1BE6144B817DD467A8CAC91FF409EE113CE9CC1DE8DB0C17687A94EC9EC08B2BFF51F2437A864342F5906985A2409C8CE82F8DB4A5FA12FC0FA7439EA413F3CF66325E7F7ACBC808EE093E5FC6B7C130ECAA604639EA27B0DB0DC333884C9894420C3ED9C9B9477718C7E7899731773DBA7505B4F2CDC44EE611F131D1FFBF570B1E1F51A7B8B854F9F895828C8A832EE465D0279DC908C1D9F83AB22131F4F05732FECA6BDD5E84502247255FF55C9F3EB0388077B7718BC +ss = 882D3F7190680B6DF68439A524D5EFDE787649DDD43D45FF + +count = 87 +seed = AC139B78FD16CA0F26D6D7F9E15345C888D857B1910CF38D883339B37EAD2DCAC30F7CF10176F23FF34B4488EB79437C +pk = 81CF6AD13306908DF7C067623C5FD6C9BC9820C21D6CC358CC37EA9BDEBCBEEC077D25288C1C5A646C0648DE2D20FD33683AA59374432343EFA47633F2452E5AF30C86567060DD880E17DD0739FE844C9E9D2230756928772656A5B5AF6FA5C0C306E65DF90D304FD47D5C9F70035EBA6DA539AE8B64FAFC40529C14312432337CB7519155FC7C1F43EC0AB8B78060599A0F3C9B786A3AE5F48F811258CD424A5688CE76407D2BCED50078DDA23AE71C2049C104A862BC464D5E2CCC1DDD78C9557CAB1F5A5B4B8AE6F2DC199EF38CE366E67A9D0E40CF423C7654D4FC4E1A36DDE555389A41B105ABE760617527DCB50C9F0C8D396D9BE746755A2D15787306B690A90CE03AD022C4FCCD0550EB7ACC95E8A705014F6C73D25184868740409B87B0A620BAEE2FAB3C16151D221C90838046413B1A317809854D01CDBB5157A77A6E2AD22BCCA4C5297BAFBD5A7EFEB3A2C848A287F7FEFAA72AE4823B692C3938AF5AF14011264B3037220B82ABEC1F6390BCEB3DAF7B252E25 +sk = E58F71BF175C0550A67E00E0F7B3B7FC36BC2707BF0C93047F7054814869CF7625E45647BC1547AFF288DBB90699B2AD84893F3B755D970281CF6AD13306908DF7C067623C5FD6C9BC9820C21D6CC358CC37EA9BDEBCBEEC077D25288C1C5A646C0648DE2D20FD33683AA59374432343EFA47633F2452E5AF30C86567060DD880E17DD0739FE844C9E9D2230756928772656A5B5AF6FA5C0C306E65DF90D304FD47D5C9F70035EBA6DA539AE8B64FAFC40529C14312432337CB7519155FC7C1F43EC0AB8B78060599A0F3C9B786A3AE5F48F811258CD424A5688CE76407D2BCED50078DDA23AE71C2049C104A862BC464D5E2CCC1DDD78C9557CAB1F5A5B4B8AE6F2DC199EF38CE366E67A9D0E40CF423C7654D4FC4E1A36DDE555389A41B105ABE760617527DCB50C9F0C8D396D9BE746755A2D15787306B690A90CE03AD022C4FCCD0550EB7ACC95E8A705014F6C73D25184868740409B87B0A620BAEE2FAB3C16151D221C90838046413B1A317809854D01CDBB5157A77A6E2AD22BCCA4C5297BAFBD5A7EFEB3A2C848A287F7FEFAA72AE4823B692C3938AF5AF14011264B3037220B82ABEC1F6390BCEB3DAF7B252E25 +ct = 91D25ADB0DC2F171B2B1114922841E0EF6A85CBEF27F5F39E7797B33EB65D00144D89A6076DBF68BD4334AA97720CD5C1F53061F07BD6A986FD3809119562FF629B468FDB55FE3542C6283C52D836E063B47DBB3C9CFA0DC626B96CEB2615B3B11C9AE3813CD0CBDC5812E6C9BB4DDFD93B636AB2F5BD25BF9851ED28722F78452F83A97BAF31DA8C060349BC609074EEA11EC0DE20448ADC2CFDEAF816577C2695808DE76E8CAF5E96EFC64CC8858D646F63A4A6D9BF2B76BCFFAA40DD08B2180ADAAFD7D901116F7387DFCC9EC6C9897C5AE8A631F504B611E5DB4E7E0320EEF4C2B37704BDAFB7AFB9A615BBBA2667E14FD5FAAEE006916FD36343FF661EDCC8995ABE7089E138FCE06DC8199FB0AB3D46B73B23ECD856A1F2DBE303FC905410A68AB52BD63369E2DC7CE83C83CA6203C08C70785549B29973067C850B51A20DF8E2ECFE740B088A9A03788BBE3237958495239A6D850B5973AC118328A48BD573D552A97AE0F4BE7903474227343FC63130D825EA07AA51A6E1B9A6FCDFDB2DC9B1B2CB14EEE711D96471B78C8B3B0E0 +ss = 44F2C67406C5E032106545CC7118D8F3FC0A0FF6C1EA93BC + +count = 88 +seed = CC7152849C98D5FED2813275D32069E44824ECB14EAEF425CE017448CD9A401C91C06D0F7EED6D22B7BBE8BA6C429EC3 +pk = 990F4C0DE127E2E5D3307E02AEE3CCA33BC53C2033447F15AD2AB50457759455D2BADF9EB08F68302A77DDD5534211BB310D52357B970F2D3F5153607C4114FF806A5B6173E434939896468B4E2BD6B7A775690F88DC2D879E44D5504632B2E4EC0C1826596DC4CAF3B0B6DCE76A23FC1A1D0938CB349B891DA002F49F3136B1F20C0A03A019F7E51A5ACAB26347F0B6CDAAB1A0BB93DF0FE3CF77D6971FB00AA4BC20CCE8E0F91463B8C11A47F2337DBD7750C8AD9358C00491642428F74D0CB85927F98557A706F1DC0D56F56C81453A24D3A1ECB3E6CD1ED7DAE572FB65EB0C94E8B7C3C4002B856916C1FB886A893DDB018BFCC2D967C2637F2F0AC44FED6A397E571B9EABA0D0B598212337B5AFE539CCEB7FF54CBB614D42125EDCD1DBAFC83D795EF2A1F1A66CAE1188F19DBFCEE25FC1FFF2921591BA1A6D980880952562C100B94C424DA5DF7B8556892703DCC8742623C8BB837D9A281FB6CCF3DA6D296A3DBB0EFCA6B697E81B459927B763C468A2C8AE7AC45820 +sk = E3FC575ED51513E62ABA655D24CD9C8F1C6C848AAFFA946CD82C2F1BF2E6AEBDE5660FA73356982E12999D8FDAFBB3CB186341D0386DEA00990F4C0DE127E2E5D3307E02AEE3CCA33BC53C2033447F15AD2AB50457759455D2BADF9EB08F68302A77DDD5534211BB310D52357B970F2D3F5153607C4114FF806A5B6173E434939896468B4E2BD6B7A775690F88DC2D879E44D5504632B2E4EC0C1826596DC4CAF3B0B6DCE76A23FC1A1D0938CB349B891DA002F49F3136B1F20C0A03A019F7E51A5ACAB26347F0B6CDAAB1A0BB93DF0FE3CF77D6971FB00AA4BC20CCE8E0F91463B8C11A47F2337DBD7750C8AD9358C00491642428F74D0CB85927F98557A706F1DC0D56F56C81453A24D3A1ECB3E6CD1ED7DAE572FB65EB0C94E8B7C3C4002B856916C1FB886A893DDB018BFCC2D967C2637F2F0AC44FED6A397E571B9EABA0D0B598212337B5AFE539CCEB7FF54CBB614D42125EDCD1DBAFC83D795EF2A1F1A66CAE1188F19DBFCEE25FC1FFF2921591BA1A6D980880952562C100B94C424DA5DF7B8556892703DCC8742623C8BB837D9A281FB6CCF3DA6D296A3DBB0EFCA6B697E81B459927B763C468A2C8AE7AC45820 +ct = AFEA78B52C993F7EA0E94272E89052424B908ACFC5D8C50041724FBE6E2AE3AAD10619F3B6593D3831A0CCC7D089D21600D458707C7EA1CE924F634297C7026C4461C00B07BF8401231FCDD9DC9FB7ECAEACB78055ADB4D5D55035879522E70C28775A45C96C8D439B8EC5DC7C18C1C25A03F33093AB91BD83463A16CB1BD2672A6A8259DA43F8C9E44DB7B5E81E8328AFEEC6203DFFEC1F9BF0F2F2B0958FD5AC4B37D5CDEFC1056B63B875981AAB4A857ADC087F70C9ED53DBF5F627383D8E2FCDEFBF75AB63F181B14F35B70C0D1ADDE6B696CA8BC31F6B363902DFF19712E80ACD1B891E623C5400F44CC1E98181C4894DFE658A1C6FAB305C0EAAE225E87A76E9D596D91D6B338E65A3C31E32C42F7A9941B2BD32240A3681C092C53EFEA96EFE67E583283BF6E1B4E4EAEC38E3EB3ECAD8A15735908EF30824DD0DC83E4B7F5EECBE27BBDEF9F01C2EF578A20148C1B6A0C7E69983142735C5095D09109C0A14FB83AAFC693F982FAE602C97642B32B19C17EA1B281A04D878341C564BDCAA064F242E9CD87F69629138265328EE88 +ss = 4E77D3896C5494B0B06FEACB1DB71A345638B0D8BB0908DB + +count = 89 +seed = 96D9A06F88FF2C2036FA8E914B89C765E4A510B468DEE40F914F78858C811857EFE9FD0E17C0048E7389E8D996B7E2B0 +pk = A846439524CE37BA030BB465502028F419F2A64014D9D6C5D419E0BD99144FBC3B6ECE1DFC3CD59E0240376A7A1DD1AA0748D7A92F65559C13F91304C2AC3B9FC1B870118B33BE372BE80186815B935C5C92CD4F2310DFDEA02E6E8E73F94F7D85EEB4BF03745FC6E296084EB63DBEBB0A6C3A6DF96E7A7D5D17CA50C011159BBB247F59BB9F5F59EB3DBA11C933EBB2D6D2C7117FBA4A3156CFC420EA05E6F81B802EEB56F164731EBFC4066D93C4944BBC43679A7071EB010E4A222C0A04A8EF8A3A18ADA8BE668D2EAA9780198CD827D9E7A3CF1D4BFA76C5872F0A1DBABA91E041C77D3026E53FDA38C1D5A0ECAF41E5029F5D373A0FF2C661153D0522EC1553E1B72894EFC1C7BEABB7F6991FC1E9E599743610BCB98212DC9470209A4F9043C049DCB36FDD03AEFDE167964530E24538B9C10F294B9C4B0CB8B4B9E4977EBCC006A81BA71DDE6D12DEEC7D1C8C4A0714A93BEB58A7EE3112F356813C4142DDD01F933B7B5D7A008F708D9AA12799E25B8B62627AC09B1A +sk = 470B4943F0FE7FD0D8EC5185ABA0D1DB09D112934E4FB4788B2809FD40008BE70A6B184981101724BC3D5EC5E1956B510B82FD5AD0668A0AA846439524CE37BA030BB465502028F419F2A64014D9D6C5D419E0BD99144FBC3B6ECE1DFC3CD59E0240376A7A1DD1AA0748D7A92F65559C13F91304C2AC3B9FC1B870118B33BE372BE80186815B935C5C92CD4F2310DFDEA02E6E8E73F94F7D85EEB4BF03745FC6E296084EB63DBEBB0A6C3A6DF96E7A7D5D17CA50C011159BBB247F59BB9F5F59EB3DBA11C933EBB2D6D2C7117FBA4A3156CFC420EA05E6F81B802EEB56F164731EBFC4066D93C4944BBC43679A7071EB010E4A222C0A04A8EF8A3A18ADA8BE668D2EAA9780198CD827D9E7A3CF1D4BFA76C5872F0A1DBABA91E041C77D3026E53FDA38C1D5A0ECAF41E5029F5D373A0FF2C661153D0522EC1553E1B72894EFC1C7BEABB7F6991FC1E9E599743610BCB98212DC9470209A4F9043C049DCB36FDD03AEFDE167964530E24538B9C10F294B9C4B0CB8B4B9E4977EBCC006A81BA71DDE6D12DEEC7D1C8C4A0714A93BEB58A7EE3112F356813C4142DDD01F933B7B5D7A008F708D9AA12799E25B8B62627AC09B1A +ct = CFD0861222550FDE8F2318E73FC000F3443651CDC9913F9089FB2D74714CE097E3EB5299FE94E3A39B73EE7EBAF035B10B92A65D9D7C2B539AC14A7D5D7C004E156D5028FEA586D2B5631AFF90B3BA722F4264822554C1B75B1F7A454C01440500D087C81F7F398D117836070AA0E19A0C099E4A7F5ADF653BAB2514BE376EBF986B2AA48F64C993087CF610264BB7DE399DF453FE36DB3FAF96510DCA584DBF08D1FB2CB7F08BC59BB34E1A74FC37221BBC5BA648766C814B77EE8902565BF1660BC80D8C3FB74A97C3A1E32926F22CFC71879D377A63DB0D1E1F296E81E321ACBBDD3A23097484942C7AFA34D7088A22673BFE06B23E6437F2A6000DAA9401F010BBE6053726D928FB90AE78F18422804EF8CD5E1B4010C5B740C991FF16063C44953412F5C30DABB0B77CC806FDE6208102D025B30510972E0A2BDFD7DFF80E8972A7BC2746A4FCCC603B22B1D1A11380A5793AB0FB94378617CAF500CEEECECA4DFE5D740BFDBD6AA2FA59840C5F217F663612E2E7AD16312F397EAB9C035D683328CE2E68B55C19DD885D027A7F46CB +ss = B41F3712746A65094FDC479A3AC76C79E7516AC03C6EF8F4 + +count = 90 +seed = D26CE360D399BF7B89DC364AA7AC06BB513EAB8F527383E93E30727EDC3F22C262AA0EC70257B39EDFF0630DCDC1B79A +pk = B424191885F225F3908E03A9A0B1961D9276123707A18F3A3E21D1DC22D059190F5C98E37A8819B2431D9350307BF9091399BAEEA45972F53EB85D7F8DFA24576D4445B7956C28CD1FD421B2B66386FCDFFD12D05446BBE679F0F24E1E078C1D3B78F7C9CDDCB8148CBE848A9E8CCBF066F407456EFD64D8F569AA740A3CAEAC7EABD16D176EB0AB477767119A033BDAF7C843E59D8D67D270925ADEA34C2190972A01363B0F5E4EC1EEC3D66322B84A1F5EDBE1037962637950E4F828F1E234D22674B1A83D11BA4D07CCE892A93D5A9D24F5CAFAA9CA5E5F05EAD36705A78B17FC83875645D0F25854FB688E78F0C7E10E65C4F0770CD852ED8608F9516DD37B8EE57940AC17CA394F992AFEECCF6D25AC97CA5E3896792FD28B3153D454193407AC6607888E877B262CF6E43212B2C00DD0DF890C4937FEF515A1CBF9684895CCA19CFEB7A4A3FDF2B79F83580DD883593E835EC3F54DBBABCDBB8E6C0AF5430620A6DB87BA461C8E71A96DBC01D3B3E133C1D783461B021A +sk = 6DF4385DB978D27B27D2AA5E452E4152B36F097503D9581AC95FA08ED106CE84660E8A4C90BD2B22634E40769AA0090A101C5DDDAD45ED05B424191885F225F3908E03A9A0B1961D9276123707A18F3A3E21D1DC22D059190F5C98E37A8819B2431D9350307BF9091399BAEEA45972F53EB85D7F8DFA24576D4445B7956C28CD1FD421B2B66386FCDFFD12D05446BBE679F0F24E1E078C1D3B78F7C9CDDCB8148CBE848A9E8CCBF066F407456EFD64D8F569AA740A3CAEAC7EABD16D176EB0AB477767119A033BDAF7C843E59D8D67D270925ADEA34C2190972A01363B0F5E4EC1EEC3D66322B84A1F5EDBE1037962637950E4F828F1E234D22674B1A83D11BA4D07CCE892A93D5A9D24F5CAFAA9CA5E5F05EAD36705A78B17FC83875645D0F25854FB688E78F0C7E10E65C4F0770CD852ED8608F9516DD37B8EE57940AC17CA394F992AFEECCF6D25AC97CA5E3896792FD28B3153D454193407AC6607888E877B262CF6E43212B2C00DD0DF890C4937FEF515A1CBF9684895CCA19CFEB7A4A3FDF2B79F83580DD883593E835EC3F54DBBABCDBB8E6C0AF5430620A6DB87BA461C8E71A96DBC01D3B3E133C1D783461B021A +ct = 19FBF007137E648B4D8E6FE9C6B026898EA9E7C8FA08E1AA21D1CC66EDFABD7AC3F7A115C64F365D50CF249BF0DC3E69FE26CCBD7491C4D069A8D253A88D3C4EE200D9F1C2F9D295FF665832CD65610B48E22DA3541B9510BFEA0CD04E522FF25FF865F687B0143FE9DE6E73ACD9AE5E4F1A9CF339AE6C0004F51A7E27333826313C571A831FA463CA40B4C284A9D18678FEBC12FE54FFB5149E7CFD083BA002B81F904E05EB6D4CC418E01EB536B89ABE956D62A288108E4CFF63661340032ADB290362699BF60C89194330E8BE71941C7F5994390EBD0E1488449828B1FD5E677453E3CED821D910BEDFE110BD425D90555454B8092C072F367714D8BCA226DDAA0BB5BC685596AD0F5CD195AA8BE36A17BEBA9783BAB4C5F3B9EE7165B2ABABE585A86005D9827117773F9A556C604B9BD91E41E7ADD4356000C9313B8B64CECB975BA5C66C968D24E22A4BB15EC17397DA768CE5CC49C6D926AB8386F34BEFDBDCA99D00FCB1E07320DCB2D345D1579922E5AC043CEB810F98999118A6C1BC8D6B924D7A52A61467A2F79B6AA4EC5A8A +ss = 9197966351C732D5EAA75C7CD6E38B416B2CC72F02B06C18 + +count = 91 +seed = C5856298C3CB6AC9787A0F30938537AB2635B96F6D19CC9522063360E7A5C88E644929D2879180E3E5BCAD2422B7CFC3 +pk = F361885521DDD8390666967A8AEC562395B51D40C56E6CE0C739AED0995605987F846E0ED295453974A1CA8CAAB4D4179EDBA830BE2897A2DC961B0ED1C7038A603A909D3A67ABB820474AA5B576D8C3FCEAD2B3E3E0082227586EEE253FF4F608CB4F41B426CE34C33C4746921B731218FAF5CDD26623F1A6F80EC13C041011F37322C4FE8B67987B4A8FBC5383CA4298B90E1A3E468325E0FED1F9101EB58BE72902971870DD74EBAC1C97CFD8E5A57CA9E8C8DF6DF6C6A2824BA43C9208C8CA360000EF7B775C3C08291687A671052151E6CB2821500A0C4A50D0EF258BB4971DB335CEBF58A2BF8CC9C533CFE0150C0546239FFD550E0BF9981A1CADAD08ADC22964FCA003BFEC5BD88B74D954F35AF61B8A142B0DC063A7AEC30C39173E4C2FC9E0C397A51742BFF17AB303BA0BC94CF38B8DEA92968A123CBB63F80206DE2F3A441BC35BAA56011368F77145A802341636EA94863FF843080612968E746568783AEDA5FDEDA2C50454E353D9742AE8A3892EF053AEEF21 +sk = DBACBA825728444921B227CDBA54446B3F6881B47BE9CD02E15274A8E2BC08FE818B117BA28C5DFAE74D54FCDF6F20052F79BE333EDC8D0EF361885521DDD8390666967A8AEC562395B51D40C56E6CE0C739AED0995605987F846E0ED295453974A1CA8CAAB4D4179EDBA830BE2897A2DC961B0ED1C7038A603A909D3A67ABB820474AA5B576D8C3FCEAD2B3E3E0082227586EEE253FF4F608CB4F41B426CE34C33C4746921B731218FAF5CDD26623F1A6F80EC13C041011F37322C4FE8B67987B4A8FBC5383CA4298B90E1A3E468325E0FED1F9101EB58BE72902971870DD74EBAC1C97CFD8E5A57CA9E8C8DF6DF6C6A2824BA43C9208C8CA360000EF7B775C3C08291687A671052151E6CB2821500A0C4A50D0EF258BB4971DB335CEBF58A2BF8CC9C533CFE0150C0546239FFD550E0BF9981A1CADAD08ADC22964FCA003BFEC5BD88B74D954F35AF61B8A142B0DC063A7AEC30C39173E4C2FC9E0C397A51742BFF17AB303BA0BC94CF38B8DEA92968A123CBB63F80206DE2F3A441BC35BAA56011368F77145A802341636EA94863FF843080612968E746568783AEDA5FDEDA2C50454E353D9742AE8A3892EF053AEEF21 +ct = 7EB2F3FB65C64C2440C51F620139B29D718D5EB4088BF46B572A42F5497D77A3E678E2761ED974DB6F6AD31BDD55C362FBA140A7F46C658C79CA68042AD400CF9F557EB85D8C63C097E916485FE985797D3AF3867E35101B6C3F0875FDB54B0399E11A399131B8A75F6AC1F10A322D49ED5F7F92152B7247FA590C903F3C5A6C611E951B565AA7F0DF6A0D6167016BD8F38DBA95B39ABF1A51D1195B8ED0F34213F1B69A67F0F8A70ECBB656EBEAFB6E51A4AEE9883020FA553618571941733A7EEA4B09E28CA1F571DBADB6E2EFDC4906C552EB2FFAF08FF37D171B3B4791C4E98F465D8835ABC902884C52BDE74EF1F3D111A77834C56F2446791DDB8DCAE9E816CD8FF51A1145D050EF023DD15C116854B1D91B41C3B7063B73E7E15063AFD6D1EA9A159FFD1437E1E12A350956A1B7B61C004180508176A0361D4A2301A64D1F498C7EC19FBBC5E7BE78381EB22E096C6311C183C01B45B66FEFCF42962CB44C95A50166B08FEA6DCB05C34E90C202A65C29881B9D7F913568E2429A65C5A70B311ECCD242676C72AC494A4883A5878C +ss = 010C547D684CBF7E3EF15DEF1EFF805B2648CE3D55141115 + +count = 92 +seed = A28EAD0A08E7228AEFF602B16A1E752278B8ED1E91DAC67994F5ADC372E1D82F95CC390CD97AB9212275E0566C833FD8 +pk = 26C6A6EB7C3975D91BFC6F1958CAFB8C323AC01FA62675E7D0F5ACCBC514F5A53851F8869B4747747CE288A7531EC97E1EC481BE52175CC91434493709C5261DE8819759F8B1E10D0F2E3A08A1CBAB97790CD57C3D1BFEBEB47832A584C955249A75EA121800111AC674186C6E75F15CDB10C09D81EBA51F1691D8B7CA33458415D787235BEE9A5AB1D8718F1224DD47FD079B8E59DF02C756A1E05AA1258242D0E4499D6D7016538DE26D3A11F7465797BF2CDD27EC837AA924E5B6010379032BC56052B5802E15B31C00399FA216A6040AD49F37E5EBC4E96B27AC141400ED9515F90F2EE500C405FA20F173FA84367C14609251643B2E04EB2701F906A2254634B6B6D85D203633CF014BAA3F51450A1D570D0EC878BEBC5768D8328A61E2AF98ADC74FC5BB925B19D487606ACAAA7A4FE31471709E296C6B39ABCB409090C06D455E31475A4F74EB271E96FDDD644F67D6FC1AA4D99CC3CDA1542CD5AA6200B8920A65D9A97217E20F940B23BBDFE0CDBEDDA51CCB8EE205 +sk = 690EB71FD7052B906EAEC09937A8ED374E0B02AFA27C2F1481C38C2CB5CFAFAC81B96A810AB749B61806B6D54C9F8CF4BF1BE0192423280F26C6A6EB7C3975D91BFC6F1958CAFB8C323AC01FA62675E7D0F5ACCBC514F5A53851F8869B4747747CE288A7531EC97E1EC481BE52175CC91434493709C5261DE8819759F8B1E10D0F2E3A08A1CBAB97790CD57C3D1BFEBEB47832A584C955249A75EA121800111AC674186C6E75F15CDB10C09D81EBA51F1691D8B7CA33458415D787235BEE9A5AB1D8718F1224DD47FD079B8E59DF02C756A1E05AA1258242D0E4499D6D7016538DE26D3A11F7465797BF2CDD27EC837AA924E5B6010379032BC56052B5802E15B31C00399FA216A6040AD49F37E5EBC4E96B27AC141400ED9515F90F2EE500C405FA20F173FA84367C14609251643B2E04EB2701F906A2254634B6B6D85D203633CF014BAA3F51450A1D570D0EC878BEBC5768D8328A61E2AF98ADC74FC5BB925B19D487606ACAAA7A4FE31471709E296C6B39ABCB409090C06D455E31475A4F74EB271E96FDDD644F67D6FC1AA4D99CC3CDA1542CD5AA6200B8920A65D9A97217E20F940B23BBDFE0CDBEDDA51CCB8EE205 +ct = EF5A3056D782979E88000A82AF2F6EA2CBE309983017A9271990188E85AA70C32FE5DCFCD70BF681A36DBAD6F631E8010E725A8C9AB0C0AE3E623F9FCF162F776A1B79C77F0B1FA710054AD4E356B2C249524DEDAE9CDCF66CEC9C73A37000DF7F807E2A81BD39C2ACEE17D2755794800BC1745FE0F59718B995F10C060094909C536219C9C6CB0C569F5E68255FFFD165F29A93C1791D80F757021B9B4BEEB58171A77595E522B179AE5FA5DB8EC004F6FE1076518DD98FE841A99837ECEC81A68A7D1A2866E23A31ED3B9BE5267BE8130891A35FF7BA8C2CBDECA3B5F36DEDFB3A28B74FCD0A8C4C99C055FF7ACA83E01F104343046B7D878F3A2FD0379ABDFE72BFA5462674168708FACE1AC610D4AD54B626DA601CF0B4F35B10F3619C93D5C9D1C85BC5874D24E44A2E3BAC346B6CE0C67AE6AA66E30E650B9001282948F74FCE4179D16216ED1ADBFB96DD970B8DE151C1C588AB89A4BD0C7804B41C2BF32B836257C1AA612E04C6815D2517B1DA4EF127CB0DC0160032624F470CEBBAC097B636EAB343C4DBA74B94A0D22DCD7061 +ss = A14DB72B151FA84E5CB3EF9AC1EA2AD63B037B0C754CEE07 + +count = 93 +seed = 92877D706DAF88EF3412EB143DB8CD91BC047A9A43B7ACDAA42523560DEE4C172697BE4332042FCAB91135839BF74AB2 +pk = 47596EC8F229F268E877C36911ACC64EC804A5F4DD8477CCA059D1E159BD442D2446B33AAF56E873A871DB416315005DCCBAE45CF1A9E90470893D91BE7029B8E6DB57965B4E252C8EDA47E770FF72407E813F8A19A850A2B4E06E1E1149A68164FDA6B81C465F10E28CDC30AE5842CE27A3C2032596FB6FBBCF013B132F5037B8BD301379D60A8BBD610D964FDDE236C1F013DCCDEF1D583D1E593E3DE0B27B81BC21DCA0C51D007455338A57D7CBF3E1A822188CA0C4222C2373DA228EBD03F94064C9BB2374196B230B00D51813A6D3D8E55D11363B8C7A3BEA2D460057B7D67832238032D7ED868ADA9C5B4E81AC9563177B0A0DD82D0338FE0E115F2379ABDA40F1E06D118D57B7C545051DD04B47F14112CB4082EE3568B20E4FD1F5D4761FBE424284967989DE76F980275FD858DC803AD10D54409B581523322C3B91FCC33E22A61D4E36665BAA2B2ED42FEE3C878F7BD5E3465F9F2E2ABBF408FF09A998BFE15DEF386A4B838458AF7390C3BFCF947381112E104100 +sk = 32E0EA9089FA928482C0770DA545AF1BB871A03CE3860413C06C5BEF7B6508409DAF847A64C8D30D0974FD3BA7476DC76C46B458A036D80447596EC8F229F268E877C36911ACC64EC804A5F4DD8477CCA059D1E159BD442D2446B33AAF56E873A871DB416315005DCCBAE45CF1A9E90470893D91BE7029B8E6DB57965B4E252C8EDA47E770FF72407E813F8A19A850A2B4E06E1E1149A68164FDA6B81C465F10E28CDC30AE5842CE27A3C2032596FB6FBBCF013B132F5037B8BD301379D60A8BBD610D964FDDE236C1F013DCCDEF1D583D1E593E3DE0B27B81BC21DCA0C51D007455338A57D7CBF3E1A822188CA0C4222C2373DA228EBD03F94064C9BB2374196B230B00D51813A6D3D8E55D11363B8C7A3BEA2D460057B7D67832238032D7ED868ADA9C5B4E81AC9563177B0A0DD82D0338FE0E115F2379ABDA40F1E06D118D57B7C545051DD04B47F14112CB4082EE3568B20E4FD1F5D4761FBE424284967989DE76F980275FD858DC803AD10D54409B581523322C3B91FCC33E22A61D4E36665BAA2B2ED42FEE3C878F7BD5E3465F9F2E2ABBF408FF09A998BFE15DEF386A4B838458AF7390C3BFCF947381112E104100 +ct = C78340426813BE7C899EFB1EC325E07C38AA2149F9E1154DFE6A5F5018D543739D6BC9390AEE836D128EF051635EFCC311950BCD6512B8B3234A96AD1B1C2D15FA64AD1854C3ACCA42F30FC29211C39E95DD8AB832F8DFDCF681EDEEFC854D8C59528D4D6C7B568BB2E0BFBEFA7708CCC86A07555DE846C760F3E9E0D8075D90586AE32E4C8B3CD6265F8721E9622E968B410AC5E7236A54212453A28BA27D81B61572C4240630341BEF8D8F00B7AA81EE6512FECC17D77F9DDFF7360DBFEDC57F8142FFCC0E033E66AE857393AC3DD8B417B8DCA7DE559F2DC9BEB7A37414FDA3B5871C2A8D8D6E1D165BBE23434B73AD2030FCCBD2AEAFF40F4527B5B2E738D1C7B97DA2AF4C8715B2B1B00BCB6DB95FC526C445EA50CB4CF7A32983E684B72D5456D2F055B7C0B40A83BF66617AA57A198D20CE2D0915EFE623ADE1329E4AD3764D2A84AE2656CE810866E461CEDEBA46A47AA93930CF994D27AFFDF885D2A5467DE3EC25080D4CC85849C36765B0E54E74BF8EA8FDED6213AEA82BECC6DCEF6AD43A37991831A259D7FAABE1C85457D3 +ss = E36C98F835D5A87FD733DB9B9B18A47C13B892489ACF18B8 + +count = 94 +seed = BB4C0082CA4044B1FF60B036C9B0E0495D58667156786C530BC69D949A13BFAFF53798E456423D7A0E162A60039367D7 +pk = 8645941AC39A55345AF9F2755FD29802C1AFA0ACF9A8ED5B977299D6A20B5495D47D929019A0652BD250552DD60A2920506C4D79322E5A264B0133AA2DCD2406E4AD1ADCAEC4B25F03BB977749C8EC2FCB2942163B438D7638F593AE576FDFB4DDECD2637A2525387F94DEF7DF3ED08D6171D305A32180B6EFCECEC3FC1510D4F0A5E2E620F299482E9A10581AC3214B43CF57ECCD54803A0DC9371F104A42CFE07BC53FBB460C3E936A00487B1007DD27F2CFB4F6ACDF90066C687E0ABFB26FB7D03F2BF42B634596A1DF16FC5C9F4DE9E724A9EC7B702AEC40AC936DCD4EC287B1D4AAD564115F2A00EA2E2A8754572931896230F119DDC86FD73215A6523CB550D8B23D64F1A1BF1F1BDAC23733A591C8DAFDE26543926BBBE7329A2E21B34706226718427DC24FC3BA2C217A57BB7324DDCE5C1DE642920D246077265A018C6DE1D0824445A0D9413A0461C60A89DD72D697D7208509AD360BB655F9E5D52FA3DE8937BD9AFA810F8116FDB7E8358649FD5F3C7078A26224 +sk = 6FB2EC719F2A0DEA152BF3F64B9D148F8AB8BA88F64E61F54F797C007E4061F95C7D56CFC7EE5C49E849DDE3FEA8F25E7876DF2A18515C048645941AC39A55345AF9F2755FD29802C1AFA0ACF9A8ED5B977299D6A20B5495D47D929019A0652BD250552DD60A2920506C4D79322E5A264B0133AA2DCD2406E4AD1ADCAEC4B25F03BB977749C8EC2FCB2942163B438D7638F593AE576FDFB4DDECD2637A2525387F94DEF7DF3ED08D6171D305A32180B6EFCECEC3FC1510D4F0A5E2E620F299482E9A10581AC3214B43CF57ECCD54803A0DC9371F104A42CFE07BC53FBB460C3E936A00487B1007DD27F2CFB4F6ACDF90066C687E0ABFB26FB7D03F2BF42B634596A1DF16FC5C9F4DE9E724A9EC7B702AEC40AC936DCD4EC287B1D4AAD564115F2A00EA2E2A8754572931896230F119DDC86FD73215A6523CB550D8B23D64F1A1BF1F1BDAC23733A591C8DAFDE26543926BBBE7329A2E21B34706226718427DC24FC3BA2C217A57BB7324DDCE5C1DE642920D246077265A018C6DE1D0824445A0D9413A0461C60A89DD72D697D7208509AD360BB655F9E5D52FA3DE8937BD9AFA810F8116FDB7E8358649FD5F3C7078A26224 +ct = 35DED98A8846D0BF13E0E1B6DFBE6F7118BE573D6CEC1F0535469B5197AFDD194E67F0AE4E9DDB125E39647F4AA4D0FCA6D17072E25993BE8717EB6F2CE40A522E50BCE44DE3203F4969CF6347E127EF0AEA4E933E2B8473C244830F29E42E0DABEF4487824458A433A6123E1C89F1EA9C042DE59DC51880B43109AB93301166F7FECE1C71E4684AA649A1C151D03372C4609E60E97B978656BC7A46DA7E0A99C97EA1A068C2322229081F411BC7386332FC46135B8A86FB4257326014E863E6DDB8DB0D9CACFB6A294462468A87370393C6BABFC13B2BF1D49490DEDCD30A6275DE0865DD1131648CF90B3892059DD6308F9A3CB55366A9220CF313C738126CF353111D6F31711544113F2FE03FAAF50F35FFC8D659FC39C4E224C7CC96061B8918B05BEC6F1B1A1A58443E523B90C34A0C81B8432D3C18AC8C053A0BDAA8FE04256B2A6DCA07E22801CB697E89601ABC0A73E709DB116633AE93904E7E735B8F70D016BB29C29E5CE5AD5790D3C05E44D8CED98F791CD6DC1C1020FCD1CDE1EB6DB80C8EE33C47E3A0DBB49DD59CC256B4 +ss = ECD17431A46D090C552345203774607486E221ADA06125DC + +count = 95 +seed = 121D90E70AF6204445D0DEB28AC0C108262719E9FD3476ACA74BBFDE89FAF04D8D5F89A624E8A75DB80431F0D10AD28F +pk = 41C6DCD56CBA40CD98238A09982EB9AAA87238AEDE1D0B4F4297A93C7CC2E2308CC606D03B867D0B2BE1175A18795FEA0C064C58450E79C6705ECAFA746430254DC5FDAB5742C7FECE43B114EBA62376F744D7BCFCBF9A5C0EEE30E63AC4C407ACDA5E65BC9D29E26CC9EE5596210196E83335A148EEA7AC00A0BA482331FA7732E34AB0B9211FC8B640EB45861B45ADA7C561CD8C747E4CA6FA8246FC6F410A8FC1D4558ED912E5B7FE655FB151A5D942A15C868AE6E2FB10BCE30D283DE864EAD08FBBA1D83E1FEE680341EDAADAA047928E8FCFED06ACCAEA7777A46E938E353B329DDD01EF0885A18EDC15079273372180D1142171C4DFEABB2B7A2A1A2E38CDA3EDA2C7B2336B566FB83590464886787A94A9B93B3E6E84AD2D6851A7445604B745EFBE7179BCC954D15903E1C8828059908868D4062BC8394F35FB49ED7D34DC18D9F4D4789DCFA7C02A2B9A06624BE5A1527D7419CFC25B234882C971EE7B0269E40A1CC2A10CA4CBAF8AF339EF80CD0D68014CC51A09 +sk = 527FB88C8BD9A4D6031DAD15E63878ABD2B559E7E08D61F6E32D432B4F9F751BDE0496C580A181FFED762AA35454A02D3F1F47EE0394C80C41C6DCD56CBA40CD98238A09982EB9AAA87238AEDE1D0B4F4297A93C7CC2E2308CC606D03B867D0B2BE1175A18795FEA0C064C58450E79C6705ECAFA746430254DC5FDAB5742C7FECE43B114EBA62376F744D7BCFCBF9A5C0EEE30E63AC4C407ACDA5E65BC9D29E26CC9EE5596210196E83335A148EEA7AC00A0BA482331FA7732E34AB0B9211FC8B640EB45861B45ADA7C561CD8C747E4CA6FA8246FC6F410A8FC1D4558ED912E5B7FE655FB151A5D942A15C868AE6E2FB10BCE30D283DE864EAD08FBBA1D83E1FEE680341EDAADAA047928E8FCFED06ACCAEA7777A46E938E353B329DDD01EF0885A18EDC15079273372180D1142171C4DFEABB2B7A2A1A2E38CDA3EDA2C7B2336B566FB83590464886787A94A9B93B3E6E84AD2D6851A7445604B745EFBE7179BCC954D15903E1C8828059908868D4062BC8394F35FB49ED7D34DC18D9F4D4789DCFA7C02A2B9A06624BE5A1527D7419CFC25B234882C971EE7B0269E40A1CC2A10CA4CBAF8AF339EF80CD0D68014CC51A09 +ct = B5956BF403C0CB061B8D63A42E855EE5E6E63FE882520210B54C69803C619B22FB06738FFBE3CBB263E0503170A407212C58052F5DD73BF4694BA992BDA40DA8BB16025D0F86560B21B876B8805DF6C5C6296B84D01D866F17164103C0CDF3D601F867F99FE10081153126ED60A68F04D7CCDF5C87863A0F35DD1337C916E714DBA08AFA092843E3D15448B9A35FA62B026A7103820F9B641AEB0FB87AA227B26A1A8E8EE5A8DEBAC45BAD8A5E2E6042CB2451D19ECABE4D8FE1254020EFE25D9A1C2459352ACEE5EDA84E939C83FE19C7162DFFB17DA5C318C0624300C824693FE292523E1885948D168BA21ED2F2BAA77E3064EF776683F100A71E19C37475F66418EB5A8FC983DF5A4DE8B7FC638EF45AFEB3AC9FDF12924B657EFE9786569C1962BD4A551B42FEBD37D256A9A199AEEE86F75D0E7ADC41503EAFAACD919BBBB338CB03D6152EBD4389C18CE6EFF16901A12364DD31FD6B3856FD15F7FDC0FBF47BB6650F44549C04B0EEDDCA0A34EB386DA21EAD88E8A6012CCB381BD4435743FBA5982813B2F155E468E3259D4DF74D +ss = EB336F774D19B142F59AD745419C288CD4876C478F8D923F + +count = 96 +seed = B3AC6503206ACCC2A92CBC210D020A2654726911D11CE676AA04FEAA08AF1D20C654E4105883AE470EC3AB299075D420 +pk = F9A032B24B86F59D1D4C97C3DF83534D34D53F1E2DDE8BEAC479BD1E9D2056FE39497467F6F2B86B921C7E6A82350BDA85762E76A101E90A7C770BB4138E203FC75942726185355C99CB4B1A96C76650FA08DF3B1EBDABBBDD4565410188581F67387141C223D4FAE6351D406F6582D62756006577638F6F70828608DB1FED2AEE76FC2E685956DC163082ECCB94CDBFC88EC9BF4548871F26123307F88CC9A5B0420EC16DF2AEA2B13667CCA903EE30A57F318E0F8DEA3C484A36153B702CB8574D06FF407DBA003F334F8ED0B8188890B588EEE8CFC28C056F5779FE0D2F7CD0D1D0D8484C08CFE74EE94A616E8525B9D1521FB36D06639D74B433DE4188EA3E794660769DE0F1070B9431446EE67E4E53BDC57C6B4C9F5CAD13EDE1FCB8BB2A1ACB2DCA5A45FD07EF1D9D480A535688E66A92110F80A0E6C9024891C6D0E545673C50AF4AFE1524B66F68EB29942D1E9605B20494AB511C0A783FFBB6990508AEB107833926F7FBBE426F80CCD506B99D77B95102AAF6251F +sk = AC6FCFAEEEF795B6EF9E062F02BF42975FA01E7D91BA832F5AEDA108EA4D6C6BC0FB958286850422BC357CA67B83C986048E0D0087FA110CF9A032B24B86F59D1D4C97C3DF83534D34D53F1E2DDE8BEAC479BD1E9D2056FE39497467F6F2B86B921C7E6A82350BDA85762E76A101E90A7C770BB4138E203FC75942726185355C99CB4B1A96C76650FA08DF3B1EBDABBBDD4565410188581F67387141C223D4FAE6351D406F6582D62756006577638F6F70828608DB1FED2AEE76FC2E685956DC163082ECCB94CDBFC88EC9BF4548871F26123307F88CC9A5B0420EC16DF2AEA2B13667CCA903EE30A57F318E0F8DEA3C484A36153B702CB8574D06FF407DBA003F334F8ED0B8188890B588EEE8CFC28C056F5779FE0D2F7CD0D1D0D8484C08CFE74EE94A616E8525B9D1521FB36D06639D74B433DE4188EA3E794660769DE0F1070B9431446EE67E4E53BDC57C6B4C9F5CAD13EDE1FCB8BB2A1ACB2DCA5A45FD07EF1D9D480A535688E66A92110F80A0E6C9024891C6D0E545673C50AF4AFE1524B66F68EB29942D1E9605B20494AB511C0A783FFBB6990508AEB107833926F7FBBE426F80CCD506B99D77B95102AAF6251F +ct = 8BFECB25C08480BCF0730FF016172FAA797A596A06656C978C507997E40710ADF90B480B2FAE94AC46CFA2FA3397E0D3ED3DFF54359F13BDA99BEB7EB8C1091C6377EAEA45C3D77E583D4DD7BFA46F28717BFA78C5C95DD3501D8EB63D442430DE1C05F1AAAD24B58233AC2B34DC78D795984E9B9D5F7096207340F32B3C73696128ADC44595F989A4C2C39AE126DD6708560692092CDCF3C9BC77A8857419676791AD6DEB95BE84D409B4596180AB0F465FC15F69A83A621F41390E0A7D10B270BB6B9D53DA0D65A2558ADF52163DBE4DF75C4BF467CB3C2499368294145F4743990E68E98326185E5BF9F17F8E52EF7AC625E0E6F923D797011C3986902FE6E575C80E67B7350B6386CFD522C4EEF39C8BF9DAB606332BED408FA1173F899F522A782A8B696CD52BAAC5CA8A0344F98FBEE1B0688A0A799D400DBB2A353AD8D58F5734346D6961A4D4FDD3BF0C35C98E3FA5B9C1E948346D794CD1B73212DB1C88E4A9C5B06C7B3BE836BA7FFA16F292BD7124AB115FE47C3D918F64B9E902B5F1EDF6E6EC6C90615A8C926CFBC6015821 +ss = 9C09F9F457B9A961DDAD79027B92AB15257CDD6FEB7E91BB + +count = 97 +seed = 59EFF60B1EF6185DB34EE1E3B1DD2F159106CECEAA79BEB74923B4F5623D5BC52DBF5D2594A1F7C6C64D12CF144E9ED4 +pk = B28C95BB2C8D833C8CB18B44262DFA01A4E80466D4FB3FA071CBF1BE61F4C3E5D4C2E6C9F9C2E03B01395B177B3B17F520F64CE791483CA1AA78BAC4FB8031165D23AB7E3D7AEF1BDFEA0248E75B09AF06703800725C92499929116BE0DF70EAC1567FC6FA85656170E89F0663620EB17227ABBC8466139EA471D9458A3F3DD8BEEB9371C75DCB5C2EE835AECB50EBBA7052F2BF7FB58C87031C74EAA06FF2981B21885FE3A3C1DA38F486BD983E98A137BF6951A7992F0FEA6D8B48334E333490CF15F350F6D3BDC911F8C9663EC0FB30CDE95B8F42D1469DCA0A98927F9FB91F63BA6490B64145CEAAB0A5F71DAF65399947772DF123CC8D3E3E26CFCE8086EFE0E8B1A2ADA6D35AFD4B7F8CE0B4DFB986E9F0288D7D5657C47DA3F18C7832D89EA472943AC26FC2D2B9FF8770D96B70BC9E5DE5EF6C67775E30E64C51180855B0AD13133F0CBDE589DBB4122E71FE5342664F986E08DB314D3DAAB3868637848D875905324D3AC1637866550EC0EA87880D85362342CA4F03 +sk = BA2FB9318D4DBE7488057C33E95E6F054583A2800C41BB83E63F8FFDA3565C2424C89B20974B748A65A5ABA75133FCB3156DFB6626A83B0BB28C95BB2C8D833C8CB18B44262DFA01A4E80466D4FB3FA071CBF1BE61F4C3E5D4C2E6C9F9C2E03B01395B177B3B17F520F64CE791483CA1AA78BAC4FB8031165D23AB7E3D7AEF1BDFEA0248E75B09AF06703800725C92499929116BE0DF70EAC1567FC6FA85656170E89F0663620EB17227ABBC8466139EA471D9458A3F3DD8BEEB9371C75DCB5C2EE835AECB50EBBA7052F2BF7FB58C87031C74EAA06FF2981B21885FE3A3C1DA38F486BD983E98A137BF6951A7992F0FEA6D8B48334E333490CF15F350F6D3BDC911F8C9663EC0FB30CDE95B8F42D1469DCA0A98927F9FB91F63BA6490B64145CEAAB0A5F71DAF65399947772DF123CC8D3E3E26CFCE8086EFE0E8B1A2ADA6D35AFD4B7F8CE0B4DFB986E9F0288D7D5657C47DA3F18C7832D89EA472943AC26FC2D2B9FF8770D96B70BC9E5DE5EF6C67775E30E64C51180855B0AD13133F0CBDE589DBB4122E71FE5342664F986E08DB314D3DAAB3868637848D875905324D3AC1637866550EC0EA87880D85362342CA4F03 +ct = 1D355B433C42B27B5B46FC1D40B1B8439FCA38C18ACEAB23DA86FA9F33F154EAFF88A2B270D922630B3A28835AE6722FA08172ABBA60D61DB6CF3588AE8B0BC632E0F0A5EB0AEE43C2872EBB70B356D2C9962844BCD5B010253405F1E5AC6E9BF170C936344569E65A0C04EC2C992E0165D414C9484F781F28BE22A5EC21FD2C4F30C4E531BA3FC4B81BCD7DD93CA46BEF434FC0D04CD9DFA50394F343EA6A0BED874404AE3B0EFF4F4A66AFD548A3D31E05254586908BE12080FA533A13C0CE2B5D7756E2D78338913EEEB2A2DA35E8C9C0A4DD3F4D060DAD4BA7971171D12EEF9BEC8FA4C03BAE2BD5E1F829AEADAB640525F4C11E1B81AB8A5C003E25E5399F622DEDD6BA00451153AC42C15A38CA9E0F9A0B6B495AE28318951911D799A1DE8FF73370364BDBBC50929BF744062B9066D1713CC401C62E3340882556F096AC3F238069AC636548D9427B7688E211D4E51DB474EB726E3E02878B82C565E5B932B35A9AFBB7E4ACEFE3650A6C2BA1D1CD76B8216588EC5A24508323642EE2E92A996AE6C443F5D5E7E9D426B46C478E3A +ss = 3C988FB8F65F3CCF385CEDC792AFE350C019C819A697FC47 + +count = 98 +seed = DDDCA9DC31BEA737D3F474E7560B37FACB2F53C803E768FFAADE7669FF94B1D4FBD17068CFFD5DFDD24AADADA4EF6B12 +pk = FAE47FF12AD9BCD71917E48A3C8860DF4DC91E065C98D7823783244BF9345D602E13653FA41844307BF4528E88FDA69C3385C1F76BB7FC1AAE417923BF153D27145FE6B6C70240DBB6C8B01F5526E883AC30F07C99BCABF4C8B4F41C0178F34929583CCD0ACB8CCFD63126752FE9FB1EC25575ED8E92767C8FA5EF7C4F1D1A117DB9ABD1D85A1635F3EFB549BCBD4211FB451D97F880518A3130F45B6D3E2883871E2A8C5C357A5B8F2452AAA23B27B2774230F54164BA07C634C74C0930A84340F4DB33A27A81B80261AD1CA2A59A0245162E1CAAC2B227934B5DB5CB2E7FEC62BEECBD00A5D2A5C7DC2181B56979798AE0B60AFCF1D006B9BE1A0083E70171E6141BF2D0C4437428CFC3F9B3BED38DBFCA73EBCA52BB1325E177E97089DB31A4094FB33FF9EBF50ABFBB859B4208FD6540E17E869C248513741AB3F8BA290853804B383082769CBE70E14417F9372931B128D61B7C2202C5F9C3F1CA67FA960B079932EEB32AC9C8105E1E6E8F877D881193C7A0A450A4CE3F +sk = AA6DD1E5799CDF7AF9C4FC632B3EB9D51D66E85C8E0A21ECFDA268813EFAB5204EFA60F78BF81D320D01AC09AC06244F7AFBD2D80FD35609FAE47FF12AD9BCD71917E48A3C8860DF4DC91E065C98D7823783244BF9345D602E13653FA41844307BF4528E88FDA69C3385C1F76BB7FC1AAE417923BF153D27145FE6B6C70240DBB6C8B01F5526E883AC30F07C99BCABF4C8B4F41C0178F34929583CCD0ACB8CCFD63126752FE9FB1EC25575ED8E92767C8FA5EF7C4F1D1A117DB9ABD1D85A1635F3EFB549BCBD4211FB451D97F880518A3130F45B6D3E2883871E2A8C5C357A5B8F2452AAA23B27B2774230F54164BA07C634C74C0930A84340F4DB33A27A81B80261AD1CA2A59A0245162E1CAAC2B227934B5DB5CB2E7FEC62BEECBD00A5D2A5C7DC2181B56979798AE0B60AFCF1D006B9BE1A0083E70171E6141BF2D0C4437428CFC3F9B3BED38DBFCA73EBCA52BB1325E177E97089DB31A4094FB33FF9EBF50ABFBB859B4208FD6540E17E869C248513741AB3F8BA290853804B383082769CBE70E14417F9372931B128D61B7C2202C5F9C3F1CA67FA960B079932EEB32AC9C8105E1E6E8F877D881193C7A0A450A4CE3F +ct = C5622F143F95401048DC7E4EBD7AF9C8E2737F8BE2CC92B151D4FB02F348AA7D5055806E879AD7D9107BACB10533264718554A7CDE3281CCFBBE238F9E2702944E3081F48F9676EEDD488D549ADC9925859BE06C7FF13FFDEE99EB756E93E959D4B5FEA0DD5B4ADA2792B7D66BDD390EA9FF52B8BAC68C3B7372A1EA871BD2C82693743BE7E39FA6C17439ABB897E81AC4A6149853D43BE5E3D539EAFE25116CDDC000F8ADC8330667EA1EC6F6F069DF20D05248A7031CD51213EC252ECB02EFE65A22FCBE24B8CDF9D5A151F28EFB6333396590120AE85B1A3289A088EFD8DF3FA20D20DF55EDE7500D26710B1CFCAB720179126C748D2C060C023FA107E4F189B55205496BCC179D0A55BC3E0EA0DF298B5BC2E974D3FC50E8B3F537A569AC369F62D42B0BCD444D617E987833513401308A86C0D9466EA47115778C34CD9BB9E3FD00FB43B0729A6163F4B1D1B6A7F521B4CB7CE7EE2C698204742FADDEA424F95AB606B00C03E30929E4CCF4920BB0F8FE960930A177CA1E8AC9B2FC661FC19AD7F5F7102DE35751E0939A88EB1A4A34 +ss = 1CB460A2C31B62A729B4D0E781498CE4C4C8B6819CFD3F3A + +count = 99 +seed = 2A6F7386B815366F572AEB6C79E272CC21B7095FE09575F18072C9D677DA23BC9C8A4BC393B7524604D299BEDD260C8B +pk = D10B725FA678E2B06C026AF41AB8728C777C643D959AFF59DD51698CF563D171F3187C6BFCCCF8764CCEBAA6508B0EE619912EEE8C5D3061FB67B383D5DF2B9A40B7023A5D1459757EFEB3638A6834DB338AB82D3B6BFDDD498770ACFBF9CEE3ED01D6990A80A2275D19095C08E456AF201E3EBE266AC5120E7A32CEC4323F43A9E29A442EE3E29E80658F20CDBB733E80940A88EC9C07843AC7E99EFC9DD27DB34E21A5F641AC94B2B95F7CC846CEE3B3ED74D041805381E65D9F1229F11A3EBCD2B3F04C5FC6E7FA87B933138EBE473E47C6B05B829596133F42ED4BF315164B31C524B82532EB0B84E547C5649DC542B017F43460C78F10834737054AA600E6419397DD0F0D594221BB64A429E82786667B17EFA10AFA58FF5DE963D825FFD6F93A5FC9E4741C91BA79FB5C4AF49E90431E0262BD6D334E4039C67F47496690906736D3ED3138DFA9A3817BF8886F64BFB686BDB1FFD20639525CA9BBC2DD5F57D494E20A88591BB7DBE887AB1E89BCA517BE5572DC9F3F40 +sk = 195D6C86A3DF4C21E3007D7F2768B43C74CB3060E0ECA77FAE77E0F9F21EABD8C0C6EEA7767F4E10FDE5C2D79B8400BF96B19014B457EC01D10B725FA678E2B06C026AF41AB8728C777C643D959AFF59DD51698CF563D171F3187C6BFCCCF8764CCEBAA6508B0EE619912EEE8C5D3061FB67B383D5DF2B9A40B7023A5D1459757EFEB3638A6834DB338AB82D3B6BFDDD498770ACFBF9CEE3ED01D6990A80A2275D19095C08E456AF201E3EBE266AC5120E7A32CEC4323F43A9E29A442EE3E29E80658F20CDBB733E80940A88EC9C07843AC7E99EFC9DD27DB34E21A5F641AC94B2B95F7CC846CEE3B3ED74D041805381E65D9F1229F11A3EBCD2B3F04C5FC6E7FA87B933138EBE473E47C6B05B829596133F42ED4BF315164B31C524B82532EB0B84E547C5649DC542B017F43460C78F10834737054AA600E6419397DD0F0D594221BB64A429E82786667B17EFA10AFA58FF5DE963D825FFD6F93A5FC9E4741C91BA79FB5C4AF49E90431E0262BD6D334E4039C67F47496690906736D3ED3138DFA9A3817BF8886F64BFB686BDB1FFD20639525CA9BBC2DD5F57D494E20A88591BB7DBE887AB1E89BCA517BE5572DC9F3F40 +ct = F80525D9BE49304D5C07F0B9A916080CEC3CF99215327586451511E8FB978C5CAF64CDA28AB3A1A1D5A09BFCB9E67CC2D3131E9072EA717A99CA4E461B1C310EA1F1D92E1C40E0E8B0C907C8556CF1D840B41F4A6D95942DEDAF033AC2F8A7337654638E81BC0169856578DC858299D86876676411F613F53E1B4D4E1E31E7C6F9050966BC9FBABD40E92C76E5B1EE0DAF99C92B7B8F5265D371B237213317D4503C1064325C3B487E2A26BE76A4C51C8B3865A567947AEFB433A2FB39AE3D33D8402ADFC9CE470E6CE120BBD73232EFC6905BE5F665A56AE2C66C1FB596ABB4814D2C7E9469E3D7310295274355AA2A0A7B6217A55946B67DD8C2074368A4B00ABB0347F60129A4DD57CBD64CC7B6B6D8CBE6F02BA1E7618632F9BFDEDF4EA198DE61A6AF1E1450CD138FEBC0B392E0A267B8028C2F150AE5DF389A9041CE66D0E6CA81703F7176E357E558903EA0F2AF1E6C50A69CC46A5A2B8C2F90DDDD28B56450595BEE431CCE00D2504CA556C5C2281C20E54701C85E1D61A7B827E13D7172E3D6AF50711D70F62ADB258EE986B198 +ss = A047B7E873C8EA4ECE4B143C3E0896E9E9C7863511508292 + diff --git a/dh/sidh/testdata/PQCkemKAT_644.rsp b/dh/sidh/testdata/PQCkemKAT_644.rsp new file mode 100644 index 0000000..9788a31 --- /dev/null +++ b/dh/sidh/testdata/PQCkemKAT_644.rsp @@ -0,0 +1,702 @@ +# SIKEp751 + +count = 0 +seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 +pk = E1A758EC0D418BFE86D8077B5BB169133C06C1F2A067D8B202D9D058FFC51F63FD26155A6577C74BA7F1A27E7BA51982517B923615DEB00BE408920A07831DF5978CFDDD0BF690A264353A4A16B666F90586D7F89A193CE09375D389C1379A7A528581C3ACB002CD2DC4F0FD672568FF9050BA8365C7FEFC5E6ED089B921DE6804091A0744DE3EB14D426A3F7DA215C50312617C1C2697243980D06056F2CCE88AE7AE73C7343C0B7104C9F2870A94FED744CF6E94630514B6CEAB0E64733BB6FA67B931E5D8206010475CBE8BC587248D65D89D8CD9C8BBFA93E8B5F9EB9130773DED665D52ABBD91C4C8C255F73C0FC82501AE33330E9F308DE7177CBF83E4E26E334D7CB09019E638147FC58ED372AF660F14C194BC80E9666325C98E0F80877271D4A6BF514F603703D8A697874CD50A34D92F5AAEA84633CCF96801BD517BF425DEE4A32AAF06684052473EA14643C3D535440FB2240A988D09F297C5A388CB3DE60ED943F124034B90EFF611221F80F78EC124956338A105F6636B063D7E48BFBD5D614310FB97D86F122E4AE6F9DDF4977A93ED7D0CE2A94E346A1A03D3219CF21907B85A5BCDC713F93A4406A22E03B1655A66E1F6741A2F953E6FE0868B2614BABEF1943BBBCB1B66D3E7017E533EA84F291240B56AB33EF1DC3F3DE99DBF9E8BE51A0076E462BCDD825EA96D7F63C99177C305C257B31461F4C23D43115F0220409E8880BBB2468586D03461E807BE824B693874911B2B52AF06FDBDC47F5A0159729641A7C950AB9E03F2DC045135 +sk = 7C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2D8626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB8FAB0A7289852106E40538D3575C500201E1A758EC0D418BFE86D8077B5BB169133C06C1F2A067D8B202D9D058FFC51F63FD26155A6577C74BA7F1A27E7BA51982517B923615DEB00BE408920A07831DF5978CFDDD0BF690A264353A4A16B666F90586D7F89A193CE09375D389C1379A7A528581C3ACB002CD2DC4F0FD672568FF9050BA8365C7FEFC5E6ED089B921DE6804091A0744DE3EB14D426A3F7DA215C50312617C1C2697243980D06056F2CCE88AE7AE73C7343C0B7104C9F2870A94FED744CF6E94630514B6CEAB0E64733BB6FA67B931E5D8206010475CBE8BC587248D65D89D8CD9C8BBFA93E8B5F9EB9130773DED665D52ABBD91C4C8C255F73C0FC82501AE33330E9F308DE7177CBF83E4E26E334D7CB09019E638147FC58ED372AF660F14C194BC80E9666325C98E0F80877271D4A6BF514F603703D8A697874CD50A34D92F5AAEA84633CCF96801BD517BF425DEE4A32AAF06684052473EA14643C3D535440FB2240A988D09F297C5A388CB3DE60ED943F124034B90EFF611221F80F78EC124956338A105F6636B063D7E48BFBD5D614310FB97D86F122E4AE6F9DDF4977A93ED7D0CE2A94E346A1A03D3219CF21907B85A5BCDC713F93A4406A22E03B1655A66E1F6741A2F953E6FE0868B2614BABEF1943BBBCB1B66D3E7017E533EA84F291240B56AB33EF1DC3F3DE99DBF9E8BE51A0076E462BCDD825EA96D7F63C99177C305C257B31461F4C23D43115F0220409E8880BBB2468586D03461E807BE824B693874911B2B52AF06FDBDC47F5A0159729641A7C950AB9E03F2DC045135 +ct = 66D24BC4630B2EE312F01B26EC1D3EC1F583795EC93B90FD9B5453E0BEDA2A70FB6181C9B9EA86A9866F1468E62CE853C6C65AA5D0E4535828B3A97E2D1D31DC4372E6A36DA7B0C4733574B91CCE215086C59B54F2364F61298004C8410B17658B4021CD36859C94210DE338869CACF0E2DC11412FA5172E1663AAEBEF4B5EB0ED9175D6C86C5107DA92B8772342A2F44C93EFFE61F6C76AB8ABA194E862543EDB707E9D2EE884995B1062FE2F60627D5C7673C7AC0D15B08C2F8510DC239463B1B32AD46873F6D1CB5A8579457386FD75700989BEED2CA547FE505C581B6B436AABC0F75AD6373A08CEC1504258A972C64EC4A1FEB86BFE32ACF3A73ECF815CBC883F39B42C6429A5875BD0BD6A94CEAD587AF49AC8EFB43E1A447D2D8555CB0ADFBC9F335F1C599BC9FEAB3E4FE5F2D06D930A58C2FFEEDE0E2726EBD85EC890D1CB0E6870DD784AE30286F1A336D57FC41D2F2E2F89765C6A110853BB63E478A64D54A31A18FB4BA44FF58A3662F4D82D544BD9B0E94FC88ABC4E4D27D5F6084B5F2162B357A04A1A28C8938834ECC987E50C0A2CACA442850493CE16C047DF677097D3F7EA034BC3D2535504276003DBBEB12F1949C3D369E7EFBA09831E83D622AB2D9277F523946FBAB1DDE14015857EA47663C5CCF30BDF261CCBF31DBE2A560E96CE87FBA80B783350A42C837EB36B2F39A9FED1B649B8ECCE3D3235825F7C800834740546E0CF42C9C2C8B12495225F991B14547E5EEDB22858B26EE6E0AE13DBE3D50C6C1EF79C4B97DAD1B0239C4037C1AAC29EE1505E0E527EC81348900E7C216A1A1B34B8D2753AF2693647C412 +ss = FEE94595E8A05C50113C044D4D8558DA101035EBBF604AA41D0AAA75B8A7F786 + +count = 1 +seed = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC81ADDE6AEEB4A5A875C3BFCADFA958F +pk = EBE0D12301E2BA26D6666163DD18BA35392D8F9A4BC87B938A29C3DE7E309FDAF243191766729BDF54CE21C2A0939B61B4E456F2A2CA440F7B0618302EE6895B3C154DBC94FCC6BC2A11B11A67481718CF6CDCA734E40E80E41F2322DA4DE1C73F6EF21410B36975A44CF62325CF7F47117D10F3923B8C6DAFA48CE7B7913D8A31F3F881D2CE867AC0684760CBAF822B969690EE28914D466B1B171DDD41299E1C6E8ABFA7843136D05FC86E64D7FD996A8469164093AF569C6B582E67962FA687AFA2B1A0B506834159469C6DAC216C0970D255D0CE9A729A2107A66383107BC0C11CBC21764CDB48BEDC9903C7B194DA03743940904D6EEF6A8D7065A0E1C907E62EB5B5E7E4138ED239F3B6654F092F14069311A49DD7FD586E499AC7D23C2F5B84B805E0CCC4247F8FBA8DB2F09F1E95EB6E02758E5A9C5DF6FEA7BF0338E7B0AC40139405168BCC4FF5965FE78B3F7C58076ADB7EEA556B18DF2317153C88F7B1BE544373571F78E3FA7737F6E96BF68737A7D095503F5E374D03B5A03F9468AA71D604549CEAC13C7395D09430B82CE860D9B8117F5AFB52823B0272000A1E28AD78358A2415FC9A996092CDE52192145F89E6D3F5017F396A01CC4CB6402CBB46DE99D870C5CF1A4E4D7720A7CA3BE066C60144BC90E937DEE815230943E3B6CC3D5E4B0A2B4136B9B34BF73F38A704D4B986D14D901E72C94B256D9CCEB468A043822465D263F8581713D27966D7D5611615983EDDE4FAED6A4F1B1AE8385808405C78394E8DCAEC922B7E504C82575B +sk = D60B93492A1D8C1C7BA6FC0B733137F3406CEE8110A93F170E7A78658AF326D9003271531CF27285B8721ED5CB46853043B346A66CBA6CF765F1B0EAA40BF6723F327918FF97790AF87AD7C2F6030303EBE0D12301E2BA26D6666163DD18BA35392D8F9A4BC87B938A29C3DE7E309FDAF243191766729BDF54CE21C2A0939B61B4E456F2A2CA440F7B0618302EE6895B3C154DBC94FCC6BC2A11B11A67481718CF6CDCA734E40E80E41F2322DA4DE1C73F6EF21410B36975A44CF62325CF7F47117D10F3923B8C6DAFA48CE7B7913D8A31F3F881D2CE867AC0684760CBAF822B969690EE28914D466B1B171DDD41299E1C6E8ABFA7843136D05FC86E64D7FD996A8469164093AF569C6B582E67962FA687AFA2B1A0B506834159469C6DAC216C0970D255D0CE9A729A2107A66383107BC0C11CBC21764CDB48BEDC9903C7B194DA03743940904D6EEF6A8D7065A0E1C907E62EB5B5E7E4138ED239F3B6654F092F14069311A49DD7FD586E499AC7D23C2F5B84B805E0CCC4247F8FBA8DB2F09F1E95EB6E02758E5A9C5DF6FEA7BF0338E7B0AC40139405168BCC4FF5965FE78B3F7C58076ADB7EEA556B18DF2317153C88F7B1BE544373571F78E3FA7737F6E96BF68737A7D095503F5E374D03B5A03F9468AA71D604549CEAC13C7395D09430B82CE860D9B8117F5AFB52823B0272000A1E28AD78358A2415FC9A996092CDE52192145F89E6D3F5017F396A01CC4CB6402CBB46DE99D870C5CF1A4E4D7720A7CA3BE066C60144BC90E937DEE815230943E3B6CC3D5E4B0A2B4136B9B34BF73F38A704D4B986D14D901E72C94B256D9CCEB468A043822465D263F8581713D27966D7D5611615983EDDE4FAED6A4F1B1AE8385808405C78394E8DCAEC922B7E504C82575B +ct = D11E9753B285F87AA07FD7DFC2A2E84DAFBEC696CFD6F2FDE49FF050A44D4C8D1DE068730A503FD2BE7F6A9F7C341D7DCC8DB48DA208160354DFE8B08EE7175653D18A4223D6536BB18310950D3F525F034406A535497AC1E0131A791B5664948074047E08D4A64EC7D37060381DBC69C082599ACC3AE9E8CBC346D295FC894CC99E374FA35E5E293FB5194B078B61763E010F351296146E765CB5AABC73E995AE69FD575DA15619FC5FCA18D514C4A3ACAD4C49D6892E293EE7823964D06664A823BD43B33E424D1D57F0602BED56747B199651D3298923D4A4328EDA7D1B90E5310DF3D73888C365D8B9365CF56B3192D9348368D99D390288A4EB51B8E43F1776802BEA13FCE1C9F854CFCE0D755122BC05D18C5C4EDCD530870AE8C0BC4CA56937F3FEBD8607C5643CB893DCD12C6F204B5B5BE63157F7CFB73C8AE81A9551C097E0C78C32DECD34506652C5306571A68DF960B37BD40E15983B005F9DF5BD379FC85C1E4B66264CAE1143F4698F08131E113B32C604091436B68611E412DBC96972325A94E77E62AA4AFE04147AF13202BC45CC2BC5C396A5FDC8A0CD8B8C0D0991CEA1F3862FFE402857D3DC951AE5D7004357CFE8FACC4E45CC111803FCD78458B5CDEE24382D6D88E4E18D8CEA4EB515904342CC059795A9714FBAB03AC389BC39179C0AB5B6D0D2ED4006F94AC5EEC70CB92F02C38D22CAABB1C5415ADB6AF5BDBEC9DE8F22BA500025D5B06BB09A1F347E3C0956EAFD17FF4FD204ED4A4B4420F03D5B295242DA14B30A81BB9FE4562AB171769D621453DF8EEF703E13792303AB9728FFE8E592FDD9D4485812449A +ss = A8F68D31099FD86235B5A72D9DB689F25AE6FD1EDF0765744F83A6A6577EC0BC + +count = 2 +seed = 64335BF29E5DE62842C941766BA129B0643B5E7121CA26CFC190EC7DC3543830557FDD5C03CF123A456D48EFEA43C868 +pk = F84DCAE8F838C1F89B17F6C5E159E7AC16C87B99154EC9D00EA0F1E99BDFB70C7A82E2C7262907C70D3E6003460902618494AD5C19690F26758A800C41095430EF2AA4B1D677A4D9DEF977412349F9DDB745CD75268C9E5929FB669F6B6E710B4B03F57C2DD2E9DF2ECAAC84C59A6D99B13DB3BDB9AFB138783E21D443A5700FB1FECB24DDCEAF55B7E12EF2C68A992B7308A09360EB924A6F1C82FD39FADA40972776941FC9FE0262661D547713E96926203BD8FFC822E742A8303EE377A08716EC15840BA178DECB4CE11AF6A06D302F60F003F61E5BC2E4204F9A88A0EA17C765B38CA497D11FECDFD56E83BAC72D1A34998D055393AC0B98333E385F7AC2E84334B370A5A18D52A054F018B33D5B61999AF114B0C3D1F1623C4EB6027784927839D1985BE4F4E54E09E63BD4BDC088B41C0E9D0227FE669D5827F643CDCE7831DC1567BC78AC056E0F7B5A1F6A5D9F54BF2F2CB88D091EF9F5DBAE3EA4473C4891FC76D85F7B04E777AC222BF1F382E0D2825EF19C33FF25D430610381A0A0013B338972E9448C95FC820F87CDFA77DDAC7F8284FAF7D21641BF26D6000FFC7D4D5F1B9596F209B8DE93EC9DEF1360455D1AD235D3B60D8B3EFD9D6E621E775C594D65D58AF65E9DA578B2F414D5CB47F5B8932BE8497543FBECB12D93DF4AA7C46DA0BD0FBDA4CBF542D69D204908DCCBFFDEDD92753B09411062089A035E59C3280A72DBA84D0C2407B59A18E5A75D29F2130A26607D45D1230AD7CCD496B8FFAB71F1A990EE575FD5546D47190CA3C91C +sk = 4B622DE1350119C45A9F2E2EF3DC5DF50A759D138CDFBD64C81CC7CC2F513345E82FCC97CA60CCB27BF6938C975658AEB8B4D37CFFBDE25D97E561F36C219ADEF716FB6E3CCBFD9ACEED34DB628D4201F84DCAE8F838C1F89B17F6C5E159E7AC16C87B99154EC9D00EA0F1E99BDFB70C7A82E2C7262907C70D3E6003460902618494AD5C19690F26758A800C41095430EF2AA4B1D677A4D9DEF977412349F9DDB745CD75268C9E5929FB669F6B6E710B4B03F57C2DD2E9DF2ECAAC84C59A6D99B13DB3BDB9AFB138783E21D443A5700FB1FECB24DDCEAF55B7E12EF2C68A992B7308A09360EB924A6F1C82FD39FADA40972776941FC9FE0262661D547713E96926203BD8FFC822E742A8303EE377A08716EC15840BA178DECB4CE11AF6A06D302F60F003F61E5BC2E4204F9A88A0EA17C765B38CA497D11FECDFD56E83BAC72D1A34998D055393AC0B98333E385F7AC2E84334B370A5A18D52A054F018B33D5B61999AF114B0C3D1F1623C4EB6027784927839D1985BE4F4E54E09E63BD4BDC088B41C0E9D0227FE669D5827F643CDCE7831DC1567BC78AC056E0F7B5A1F6A5D9F54BF2F2CB88D091EF9F5DBAE3EA4473C4891FC76D85F7B04E777AC222BF1F382E0D2825EF19C33FF25D430610381A0A0013B338972E9448C95FC820F87CDFA77DDAC7F8284FAF7D21641BF26D6000FFC7D4D5F1B9596F209B8DE93EC9DEF1360455D1AD235D3B60D8B3EFD9D6E621E775C594D65D58AF65E9DA578B2F414D5CB47F5B8932BE8497543FBECB12D93DF4AA7C46DA0BD0FBDA4CBF542D69D204908DCCBFFDEDD92753B09411062089A035E59C3280A72DBA84D0C2407B59A18E5A75D29F2130A26607D45D1230AD7CCD496B8FFAB71F1A990EE575FD5546D47190CA3C91C +ct = 88F864EEBAE3CBE45A01CC8CC048257DFAC43870F232A5FC936B89C63A78A9B73BC94EEA62AB2C7AADBF1BB3C6ED5F8108E2E12D97F647A7FE7099C871379841E5556F42110BC32FC47C2DB873DE84EA122BACC143AA3EEC11C420F7136B326B0299D844D92529AAD19EB18A10D5B4BBCEEF4A822EF10A481364803CA4C69AA2C367EC74308B1AE5CF3B10CF7CC3A8C8AACBBC04031E0B7C8B11BE6E51A920C844A5770ECB880996DE82C785CF2C1DECBF6DFA763667E36FEB5929640DD7E8806C50D40EB59ACCC3236A7C318F439CB39F5475E0B8C8E2F4FC90C4B05DF18D4E22CC05DCE90FC0E541746AB23EA6E8154F86DC9F485F09CF62F9ACE3DA1F6A040D6DF926B30655CAF39EA18623D588E7BFC7CAEF25A9F14BF53EE2D8F2C4E1FCA86AD72BCACED8D2A8882C6CC06DE92C1C2241303EE4F541B04352004E356A84686F1BF253181BADE8BA18918B295E38421B0378E16751449C0EFFCEDF2D45EB24C8E275F0A1CB748F1650B296BD44F7D9FD261D76C99604EFCFF44DB82FE0BC2A9AF2EFEF204EA640FB87292B021E76583981C7184B0A94C9EEA7E0B117A867B44BF79274FB0CC7C8803FE68086D5DD4F1C318B75623B0236E45865CBA333D8AD2849C5951A5B603639852251FDCB5E5C8D29B1B808E8C0C9E204CB07EF653495096AC9236E2D03D8790317BEDB758398F6230D565A0AA01233AE536114F3E2250BB249CAFC9EDC5853E0572CEDA39E73945F03BB2A3D892B628A10D93D2CBC71D4254B4980C03223545B831E570AF80BD82D198FF48DC18382E926B08219331CFCB33A288B893EC04AF4663B8181445E8B3281 +ss = 52FBD8CC39FC5F77D544B9613452B8361BFF5EA79268331B02FF7F0EE145F54F + +count = 3 +seed = 225D5CE2CEAC61930A07503FB59F7C2F936A3E075481DA3CA299A80F8C5DF9223A073E7B90E02EBF98CA2227EBA38C1A +pk = C4AEEB71BD70491C6FC99899FB0C4B9CA202B016C985DC6BE0543AA6D72492E902F2C222F7EB1F746DAB053F2FA629212E72A7FFD15D7F1B22587698710246B7BE21D2639C9728D06076FC6A4D3F08ED65751C51ED9E05EB10AC2722FF27065407003BE6B5FD61CEF70B31BD68E642672A1EB3D53DAA159DDA75D6CF856EE5D299B4C4C6F73AB6B207230E4347DC44CE6FDF851DC679CF2E8CE2CB028B5B052342FFEBEB1F30471C748075235DC0E278ACFEB1360A550819735E0248C7C8898B49AF819A60C4C35275863D5D8A0A18AA123FBD307C59A3595746D17438D08F59802B87C5CC2BB97CAE6744DE325F8913E1A23E67976B7DA61081FCD47DE6D33795A5BE1751004572FA23FE2139B35C37B7D409598CB96DE006266868C7853B05A79DC5CCCDE29873B147A8C242A6364B96ECCD84E1532DEFA347A1CCDCB0C015841858FD78A9248A7905F04428017BCACE9C37908B210C89D70761ED87578DD4B72E56C11AADA4F211E7CECE074118EE8D494EC09B369D388370E67E68A2FE50D16AF776602A006BED79088568B4EF04DD9FEE5853C7CE02348D24A7559F67008A6407BE7564205A4D405F231DA4D7F8470ABDC9B5F687168EA45A748DD8E1A3302C07197C8474C1FEC7E79BF7AAA21B1A34B349C13531E7768F57591D9F9946AF77A4C7852CC3573BE7BA698FF8915F126353EFAEA767B8F9B96088F68A2B88F1D84B4BE4BF34D570B84A8385DDF2D1E5806F186BF345815417CDCD3F6F2FF518E261EC8577B9EE02525F6D91FFF81E49B8E32E +sk = 050D58F9F757EDC1E8180E3808B806F5BBB3586DB3470B069826D1BB9A4EFC2CDE950541FD53A8A47AAA8CDFE80D928262A5EF7F8129EC3EF92F78D7CC32EF60FCA764BCC227C19F847822FD8FDF3603C4AEEB71BD70491C6FC99899FB0C4B9CA202B016C985DC6BE0543AA6D72492E902F2C222F7EB1F746DAB053F2FA629212E72A7FFD15D7F1B22587698710246B7BE21D2639C9728D06076FC6A4D3F08ED65751C51ED9E05EB10AC2722FF27065407003BE6B5FD61CEF70B31BD68E642672A1EB3D53DAA159DDA75D6CF856EE5D299B4C4C6F73AB6B207230E4347DC44CE6FDF851DC679CF2E8CE2CB028B5B052342FFEBEB1F30471C748075235DC0E278ACFEB1360A550819735E0248C7C8898B49AF819A60C4C35275863D5D8A0A18AA123FBD307C59A3595746D17438D08F59802B87C5CC2BB97CAE6744DE325F8913E1A23E67976B7DA61081FCD47DE6D33795A5BE1751004572FA23FE2139B35C37B7D409598CB96DE006266868C7853B05A79DC5CCCDE29873B147A8C242A6364B96ECCD84E1532DEFA347A1CCDCB0C015841858FD78A9248A7905F04428017BCACE9C37908B210C89D70761ED87578DD4B72E56C11AADA4F211E7CECE074118EE8D494EC09B369D388370E67E68A2FE50D16AF776602A006BED79088568B4EF04DD9FEE5853C7CE02348D24A7559F67008A6407BE7564205A4D405F231DA4D7F8470ABDC9B5F687168EA45A748DD8E1A3302C07197C8474C1FEC7E79BF7AAA21B1A34B349C13531E7768F57591D9F9946AF77A4C7852CC3573BE7BA698FF8915F126353EFAEA767B8F9B96088F68A2B88F1D84B4BE4BF34D570B84A8385DDF2D1E5806F186BF345815417CDCD3F6F2FF518E261EC8577B9EE02525F6D91FFF81E49B8E32E +ct = AC7AFED8D2BE5EAB4E7B5633FB14658ADECC8AE41A84266051E3CFF903E976A3C9D23BE318F885BEFDBA1C41A32D0DF059D9CED6139A1D39452A5601F359A71E2F69CB0CA2AD2E3BA48F77E65E2EFF98A47E2525F4B98A232F076A99BF2A4A86C51EFFA3AA036784CAA79D170481B437781D5169DA7579207CBA22CBA467F6C717FE4FADE74EAACEB0404B18DD410A49ECCEDF1187A9E37917B199A86C7DD9479D969F5BA07DAD4AED185DEED28689EA464B0B61DEA2DAD807F1056088E2A294D603D209B6DFC48ACFAD3DB08ED047D7BE8751AEC02674E0A170AFB7BBA4B7623C1F526C347A994E2ABDBF990AC4A1A93516208577353BFB27DCE8C72A1A7D5DE92FE1D3720C3AB4DBC1E4FF67128989F937A7C639A9B46E884F72C175A3CA3E052E1E7EA9D41A74450C0211C4032A41AC92594F2BBD4C30274A0CF0FF1535DAB024ECEB3118B695EB2ED71A7C00CF89A3471DB9757680B0946D6D1959064EDEC78E1C95D8265791F876183B27CD906CC228593EB250745436FBF49ADB1460B6D54F596B00F942856792C1E0A867601EE288068132D3DA8D4E9C980FB3E4594EB7E22C3717A97364DE6612F68464E9CF85AABFE50BFE2A20910C624A10CF3E6E45377CB91780E9B6C00B1B6326E9BA5B3C6E0098CB03B946711E814854EB78792DBA97EFD0C7EBA16D345422FC5A2E2C6D4C3F41C138CFF3360FA45348BA7A955E80A2F2338F2A9EF8489FDB45EE5E50C6F9807C0B2DB80BEB37B719FCD1212C8AF9A798BF6A34DEE56FAF929F6720F95E68581F5FDE76F5E4004ED19B000F8DE5E8C97996223D5B9380E60A5167433B77C125F8 +ss = 4067DF0B490370B1EBA7995594556B209958D1F6B187DAE48362DB8A89E51594 + +count = 4 +seed = EDC76E7C1523E3862552133FEA4D2AB05C69FB54A9354F0846456A2A407E071DF4650EC0E0A5666A52CD09462DBC51F9 +pk = B3C4CAECBC77D2070650975568F5463E1E9896130023B9E16585BFE32A1A38E7096C3E09942AFD4BC9DEB0C2B80C48203C7D701EC8ECF6C4587FE3E5EF10A73650F737D116A13B8FAA92784BA9182E92EA3D1DB03C075AE40365F07C8903AF2FA5C906AC8D8876374AA9FAFE20D5A417B13CC65F60685C0BFD75BA1820737CEE71DF1F247ACE4F54327BC99622DCA7E0D0A668E1339F4AA8B38275946EDC8D7F11181EA3CDB8A508A60AACCF34C623C6548063E93A96F02E59EB321FB0B7C37C56B1065281F5B48990FFA2F2D8A48E4D506C5B18D8B4C6752D9508F4619035D57D65AE996965C58D2C5CAE0981799E498817576E2282B4D62B1B0A6048D61FDC7F91C2CBE331CBF08C1CCF0F87568E77937160CC3F44C533F40589EA78F8E1A8FEFD870DF8D062963EF3C36497F892CC539E5170B320B47798B53E0459225318A2CE1C496A51FED610E4614692CE73B67F6A0FDF8A857547B3B80DFA95C1EC060DB4AABC92C21092AABF9039236FFA9117622EA65A583E44D40783550AF011B2A40156F54406168283F436FB7579D39EB3DF7B9C55A1A035B61275AE7CBF7494910743B638D8C5C8BD0DD439D1CA0B30759DA4FEA19F0C2ED7A1149BB4CCF9E4B4E056FF9A86EA28167D1974BB51F092E22BC6D8C0391B81C1C5ED1FEE0253B34DE228ADB98D2AF1B6208B963182D822AD86399EE46FC29D5EF6FABB60A1A2391D95A85CECB308EC7E923C56EA836A0CD622A10887E6ACF3F42E2EB2C2A4241E3AC9B773621D4FF33D5EBBF5233DCF73C6065E1B +sk = 66B79B844E0C2ADAD694E0478661AC46FE6B6001F6A71FF8E2F034B1FD8833D3BE2D3C64D38269A1EE8660B9A2BEAEB9F5AC022E8F0A357FEEBFD13B06813854019994AA948403F5C1BC1B3BC92E6C01B3C4CAECBC77D2070650975568F5463E1E9896130023B9E16585BFE32A1A38E7096C3E09942AFD4BC9DEB0C2B80C48203C7D701EC8ECF6C4587FE3E5EF10A73650F737D116A13B8FAA92784BA9182E92EA3D1DB03C075AE40365F07C8903AF2FA5C906AC8D8876374AA9FAFE20D5A417B13CC65F60685C0BFD75BA1820737CEE71DF1F247ACE4F54327BC99622DCA7E0D0A668E1339F4AA8B38275946EDC8D7F11181EA3CDB8A508A60AACCF34C623C6548063E93A96F02E59EB321FB0B7C37C56B1065281F5B48990FFA2F2D8A48E4D506C5B18D8B4C6752D9508F4619035D57D65AE996965C58D2C5CAE0981799E498817576E2282B4D62B1B0A6048D61FDC7F91C2CBE331CBF08C1CCF0F87568E77937160CC3F44C533F40589EA78F8E1A8FEFD870DF8D062963EF3C36497F892CC539E5170B320B47798B53E0459225318A2CE1C496A51FED610E4614692CE73B67F6A0FDF8A857547B3B80DFA95C1EC060DB4AABC92C21092AABF9039236FFA9117622EA65A583E44D40783550AF011B2A40156F54406168283F436FB7579D39EB3DF7B9C55A1A035B61275AE7CBF7494910743B638D8C5C8BD0DD439D1CA0B30759DA4FEA19F0C2ED7A1149BB4CCF9E4B4E056FF9A86EA28167D1974BB51F092E22BC6D8C0391B81C1C5ED1FEE0253B34DE228ADB98D2AF1B6208B963182D822AD86399EE46FC29D5EF6FABB60A1A2391D95A85CECB308EC7E923C56EA836A0CD622A10887E6ACF3F42E2EB2C2A4241E3AC9B773621D4FF33D5EBBF5233DCF73C6065E1B +ct = 43488ED638F2AA31141CDF4B363261E7DCFC4D5EA9E50824DB9709306831579D256344FC3D200D308C1A0AA2C491EC101527FA32A8BF5F2F18692F5203174C11274AD47EDDDF777F30315C5FEC45C208172C8C9E5B3976123BBBEE5C23257FF8FD3569D7B276E279CABA3989C86EAAAE6071CA6AFB9AD7CD93CED61D76E01240A3D8F626224718CE0674FEBDAD5DA9DD1E9328352B8CF1A42192CCFA543C731EC1A2891A325E00FC5C3806BA6A68E69ED1352E0A45DA4FD9BED8E8589CB06C78AAADD61AEEFC9AE4E5D6203453903DB94D87B31DA3026E974318BAE075457E47723D3216B01A8B6D1B7489ED672904123691D0C1AC3EA2D03DD13F3EF434E8C4DC4C2EE29222E65B4967F2B9072B5ED1CEF0DB2372A302249C644A3B1620E9066236CA279CC5EF8E1CD1955544BB90FA21FFEEF6BED703EDFAAF476DE31EB86B1EA19B52B76D993648D18549DBB704D14B5257EBAFFA987961FB46D1A183D6BC065AF7C6A628A85EDBC3E1D596B2F2ED9CDE69B532F2D206157A42EE3DE1B7CB5F6B7005D5263FF69A7922A1445FA07EA1D7DA70DBC8CE6F3FA1EBF214B0A514AB7D80F2B6BF11E79E3D7531E082560E9ADF4EF7B4B0C59C95B450F01525D567AE45B8C3D5C50779B313416CD4973B81AE653A929011647E2A15B1618561803413E3418F7651EF97DD199CFD2B1F65A6D4F1AB0280110B9B982592CE0480CD7CB85ED3E9A64C73022E23557A2E793AA83F26C18BC5CF13D0E780E88B173C9D6A47B63019E86E73928CDF749BF5B0DB009AEEE22488CD42E3FED6DEE88F05CEBF596C5E38C998405A036FDB7539002CB4799C7BF2 +ss = CE4798DE43EBFA6B34FB7F22DA2B4CF80864D7F8EDABCDF3FD0E7BF8B0EBD3E6 + +count = 5 +seed = AA93649193C2C5985ACF8F9E6AC50C36AE16A2526D7C684F7A3BB4ABCD7B6FF790E82BADCE89BC7380D66251F97AAAAA +pk = 40F175F4346EFB9FC35D8A0AA991B64CB962F34927C00F71AEB17C2751D919C1999D4977C289919FAC44262D6CCC5B5A06D5CB984955498C806CF1D4FCBE556FCE74001444CF510E664A529301247029F7A1B8BA3A60617E6774CD1A6B68349D9B830D14E3CB40B5CEC69D0888531A554FC7176EA79F31DB1EF7A4ACD6BF904FB798B78BF88909A74F622DBDE8DF2A100074EA27C3395270670562A5D1A2165D7E8397E24682FBD953FDD31DF23C24FF63DC837682A303A85837316796C22D6CED322ACFFC0EED428A8FE4E969A391C6968F16A03F6A8F223AB5C15F42623501577B8908184AA2CC02BAA460708BC80389F9AC008E5B96F1313732291A4CD1B885056E28C7DFA90D05AF0FDCE6E9635A45DA8766D84A825B97208D71E876370EF89A08273CC633C4DC025217D628D2D12A7755CBAF5F4292511E03A53061807BAD2C2F165B48E304A5E37585F80B4C765F54D134DE0381BDAD22B379147B3E2AF92F743A45406CD11891FEECE5D1DCCB0759CB273ADC454F2EA15269F2405A340EDAD9784A7E7244E251E0EFAAC8DD560B410929D9BBB1E8F710AFCF9525CBE85A9D36AD02A80879544790885F66353286D00376A66B2FAAA3E2C95892E6517D63344EAF0578B5939AFA2C86B982E82E35F71294DE09842E2A98D3AAECA23DE424CCC5A8C8AAF34115A190A688406380451F2792D207BFBA3DAC0F6F7A8550A5076E24C0890BCF30796C7D6631D29DF8AFB80840D79826F97E86EA494E13E6CC64CC1AD9810FB51644CE66981B88436A94D06C17 +sk = 7EC408F52C9AA723D0C41D9987682A5F4CE6C9DA7CD0215AF60BBAF5484AB353A08CCF451B049FD51D7A9AD77AE14A81569DF8C9BD3A8F1EBEA86FDCFB823082575E0CDE12B4B3A846F639EB8220490140F175F4346EFB9FC35D8A0AA991B64CB962F34927C00F71AEB17C2751D919C1999D4977C289919FAC44262D6CCC5B5A06D5CB984955498C806CF1D4FCBE556FCE74001444CF510E664A529301247029F7A1B8BA3A60617E6774CD1A6B68349D9B830D14E3CB40B5CEC69D0888531A554FC7176EA79F31DB1EF7A4ACD6BF904FB798B78BF88909A74F622DBDE8DF2A100074EA27C3395270670562A5D1A2165D7E8397E24682FBD953FDD31DF23C24FF63DC837682A303A85837316796C22D6CED322ACFFC0EED428A8FE4E969A391C6968F16A03F6A8F223AB5C15F42623501577B8908184AA2CC02BAA460708BC80389F9AC008E5B96F1313732291A4CD1B885056E28C7DFA90D05AF0FDCE6E9635A45DA8766D84A825B97208D71E876370EF89A08273CC633C4DC025217D628D2D12A7755CBAF5F4292511E03A53061807BAD2C2F165B48E304A5E37585F80B4C765F54D134DE0381BDAD22B379147B3E2AF92F743A45406CD11891FEECE5D1DCCB0759CB273ADC454F2EA15269F2405A340EDAD9784A7E7244E251E0EFAAC8DD560B410929D9BBB1E8F710AFCF9525CBE85A9D36AD02A80879544790885F66353286D00376A66B2FAAA3E2C95892E6517D63344EAF0578B5939AFA2C86B982E82E35F71294DE09842E2A98D3AAECA23DE424CCC5A8C8AAF34115A190A688406380451F2792D207BFBA3DAC0F6F7A8550A5076E24C0890BCF30796C7D6631D29DF8AFB80840D79826F97E86EA494E13E6CC64CC1AD9810FB51644CE66981B88436A94D06C17 +ct = C7917F78DDD31FA2D8C591AC2E43C2F1A661AFFFCA000205A8CC5ACF2229FF98094447F99085DA98B26BBB4968E790877341E46BB6F741749D726984707534008A45267FE9D1D8A28FECA1FE2B0E7B7A8B7DF78D50150B3B0AC349C70E404FC5BD5ED62D204CD07CB2DFFF2A4467D6FB80136415883E2564E3A357FCA439AC3A274CF0FB6C3D51D87B297A57646A3BE95726C56C09DE3B222F2F9114F619C819B8BBAC45105CE76A16FBD403465D41D2C18DB86FCB19BF05AA73D532D68F65D0C1D5832C8960F83EE07875CFAEB3D5E64611617090B001E74F9F0FE80667049287D6E9E9FF70B6B3A5422AE3A2943328A7E8C71825DCC7196CBBFADFA752AA15A0B4C7D5B3B8ADF1ED683FC840AEBF45657A45E152180BBB97639C2BF6B074F2C71E1130D050392A937A9B24486052EA651FC0F22C1663F16A9029D638A6843B660C61D3856E419D3030E2B46760A6EBB75DF2374F6980D59A0DD0A30F3EC508669579997744D862442CAE658F0DCA2C1CAAB56FB2376420C7BA2065BCA2ADDB7F817F5EA79664609949ED3A7C5BA2833E8FFDE18EF06C3ADFF5A5B6226372DEF9F7DC293E7542CD05DF5C33DD9CF5AF84DCB7FE12167C6679FEC37060D306D614EC0AFD2027741B333C5020C75D6BB5A324B7AA090C9424BA30F943C3EAA5ADFF52A7A0750618AC97226B599A831E85BE7D6ED7A385FC5A761DA959ED05E26355F6AE576BFF646740E240D7601D93625EF627A4685F7A1AD2FBA492AE7FF19F7BFD7A5D1042DF59D8C5DC41A2102134AC5F2354CB72859E7BBDABC24248CE33750FD0DE1C55E3C5A17127F89E18F5E843671F52 +ss = D9EF3DBB942B9EEB02E9AD654C1F99A4FC7C2D779500C616FC7E9FB17BBACEA6 + +count = 6 +seed = 2E014DC7C2696B9F6D4AF555CBA4B931B34863FF60E2341D4FDFE472FEF2FE2C33E0813FC5CAFDE4E30277FE522A9049 +pk = 632B9557E6040D42B4B2DFA07C5B7E6A11A6920D617190C9F630A3C67C40CCF6B429350D45B1E3E5A586016BA21B41608899F4E82607AF619DD6523E09F935229504F59F7DAA52177D1ABDF5D25C97CF3A38DE650BF22DB468B7B1EA435194FB73A064FB890F41ADBD49EB69670AA18C32E8CBB3C4360F533D1A5D8323A63F60971B80E1A35E1E34C4483FD98954EBD27D8277E4855579CED9131DAED73F57909EE7E3DC91A168A9B5E74876FC2208052C0E7C87760BB370DAAAE13D6D399A64CD0150A2746004E458BB80F8BA5D90012DA0F7234D51D0A14736EEACFB9D4D5EDBFF8F4E0CC17EE6FD449F8C693DC004B2A1997164265C95D857868596D43414096E430A8D96864A863DE8D036953453B834095A5DE98C09A34D0B842A4AA92CD38B914B47940EC9807449EB689BA6B509B296AF2C5DEE5DDFD042094FCD8ED4B07BB1C6C777FC9F32C3CF9D74C2F74F9032D7FE55120FC8F9701975D91C7409D86AF5368259CF85432D4FED6E32186EA771BB3CD5284A427E56D84F2DBAE9C06FC8BE131DD730F4BC155E73A37FC9CB168731D93CF686E6628799FA2084A3F8EA82BE01CAB30EADF74689DCB56FBFBD956C1B045DA9EE242BBF347710D78056EBD898BEDDF760536D3A1EE58D489557528384BCDD6A8099914EFA04B515DADFA7F7A747BC80F3AC8B2B724678C13AE1457457D811A92C56C20AE04CB609D5815B735567BAB1B94A1C9AEC06E2E629742E6629357F8D666415CF403F2262AE0AC3B73CF817AC6B1DF2D0A1F07AF63CF9B498573B +sk = C121915BFEF6ABDFC177DAE2F5A24218F9ABDA2559AFC6741B08E0E61AB433EB84EF52DB5EAA6DF8EC3A0BC5FFA730DB0DDE8C5F38F266D5C680A78D264A7B9633D9228485C117A4D4C78E14F0C54803632B9557E6040D42B4B2DFA07C5B7E6A11A6920D617190C9F630A3C67C40CCF6B429350D45B1E3E5A586016BA21B41608899F4E82607AF619DD6523E09F935229504F59F7DAA52177D1ABDF5D25C97CF3A38DE650BF22DB468B7B1EA435194FB73A064FB890F41ADBD49EB69670AA18C32E8CBB3C4360F533D1A5D8323A63F60971B80E1A35E1E34C4483FD98954EBD27D8277E4855579CED9131DAED73F57909EE7E3DC91A168A9B5E74876FC2208052C0E7C87760BB370DAAAE13D6D399A64CD0150A2746004E458BB80F8BA5D90012DA0F7234D51D0A14736EEACFB9D4D5EDBFF8F4E0CC17EE6FD449F8C693DC004B2A1997164265C95D857868596D43414096E430A8D96864A863DE8D036953453B834095A5DE98C09A34D0B842A4AA92CD38B914B47940EC9807449EB689BA6B509B296AF2C5DEE5DDFD042094FCD8ED4B07BB1C6C777FC9F32C3CF9D74C2F74F9032D7FE55120FC8F9701975D91C7409D86AF5368259CF85432D4FED6E32186EA771BB3CD5284A427E56D84F2DBAE9C06FC8BE131DD730F4BC155E73A37FC9CB168731D93CF686E6628799FA2084A3F8EA82BE01CAB30EADF74689DCB56FBFBD956C1B045DA9EE242BBF347710D78056EBD898BEDDF760536D3A1EE58D489557528384BCDD6A8099914EFA04B515DADFA7F7A747BC80F3AC8B2B724678C13AE1457457D811A92C56C20AE04CB609D5815B735567BAB1B94A1C9AEC06E2E629742E6629357F8D666415CF403F2262AE0AC3B73CF817AC6B1DF2D0A1F07AF63CF9B498573B +ct = 9C29A12C2534F16715032E1ED62FA8E740287D0A144293E7FEB3099D5C2FF350B27759629F4A280AAF856D742F6643AA38CEF63BB4B4A4514376B1233B3D1F1CE6299F070BDDBCF90D382BDCFF85086B18388A81FF8FFD0E2326B5B8B83E3DE5DF1BEEBFF91013E0B7A38B89A04FB37840006C0241774A416136DA692092FE9FB70B8CE1B32E1A657CC0E5D6BDE51BCC8B3877486EEEAC0DCB85541B1E4C9A1BDB836F8CA29056DDCB31301E17BE77042D766D092C062D0ED845A655969B7DB3FBF774E162C219EC54BEAA4DC381D60DED23818E6148DA4684C578EEEC11DBD36BCA6C6D56EF7179E3391537EA250B7E06E130B426791728DBD48F81CC4993233366CBF169769C01B17F376860F0947517031C6A1055A0380A34CF2418644A9654576F78CC452DD3C5728270496F921AB6D64C54BF838B205B6640A4B6662D56B23B168F95F80C6D966F4035884CC88CA606AA20BA9D1635E7A867951E95E7925012028B8B1A0976224DE761EE1260CE90F0C69201BE2F45D46B8A3A492A1570228FBC83065D5F6717845CC7544A4AE7C0FC1059F4F555D59F33DDB1CF01D4E31AF76F29C2747829DA221FFDBBE6379148C168BA90C346DDC7B23EA156DD256AD194B8B8A65B61450000284CB96469EBEAE4434F0722132E09E9E37746700D5B33CA0250C6E74FF589F87DF19A6F86C9C99D7B7AD11B5D6322B5968F0CBF2E6B687F8FCA53A454069BC6CC937A49DEB39B366EC5307D0B99A8A7628C511654F9DB76773DB7254137E23F90B367101C5313EEAA222B174A0F10783994AD9D7A95D77216ECAE0C65BB64B855FD1A887389D7BC020D +ss = 83C18909FD73AD3732ED11B61AADFC25867E17CE0900C7F001293770325169E0 + +count = 7 +seed = AEFB28FDD34E0AB403A703B535296E3A545CA479C1D8148E2D501B3C8DD8B1034BD986F13F1A7B4671BE769359FD2AAB +pk = DEF8B8B4B7E05C8CF64A994558B0C7C608FBD949D2EF1B0E121FCDA0200F50C910CFDC3F842388A8F8F1C0FB80F6A3E2ABD66ED929CBA9BF207AE080204C52B65CE5A78F783D2573D6ED193A3305A6F2BB8A1D9F53E0152F4F390E94030B33F0D7074EDCDE4AFB5AEE2902D9B3E105999D2572ADFDEB37480F4D6C148ABE81DEB47BD42814BFD99E570DC4DD75C77D066BA1FBF691FB06DAF924541ADFAFC3ABB525151E8067B6EAC9BB738A3A548C3913060B0F697DDB6E78B8A029348D5E76452DC8D766F9CF31986CC93FE8B64DF46F08A43C7D80EF098B294D6409FC4685CAECA0F80D758C89DFE3906673DDB6B1F759F38BEB469F2CA2E96AAF17D5D34CC9D8D6B700056592CFB63BA00A0EF77EB05DF2CFDEAD26846E12ADC4F2E0BA6380BD7761C5C1A8FE090F3B9E4ECE454F22D72495926573F5032B06388634B6B4D0BA7B4C0AD721726A6F2746F98A1C9A68827110C621CDA6036AE46814F7839F65E91616EA6E2B5168CB5A05F8A8F42CC538BD684729D5071CDD7C980891D096DD527D0749B8D378DD2C172CBD2D3BCBCB78AB66778EDF3E16A614B42FD5738476F098EF638EBEEA67F0FD64012663C01392A6384E0FD37386BAEDDAB8F769A1135DA12911624FF7CE4AB4B7D231AA3998052EBA090FC1DEA22B83CA1ECF2B8FEC74824A1554E9B9BCBD5DB58020FCA5FDB4FC5FA75E332BB9C47FDF772CDEFD91A73A89953ADABE47F1CFD52C6E4F250C46A973D577A09FB840999FD2779D2A218796B8D511BA81D9DD435DB55D1ECE517FAC60 +sk = D86634ECF96CC2603761E284C0E36734CEDEC64E7FF486469E38539C71141C5A99DAF37400CFE59841AFC412EC97F2929DC84A6F3C36F378EE84CE3E46CD1209C584B1AC41A0F81C33043A9F815D8D01DEF8B8B4B7E05C8CF64A994558B0C7C608FBD949D2EF1B0E121FCDA0200F50C910CFDC3F842388A8F8F1C0FB80F6A3E2ABD66ED929CBA9BF207AE080204C52B65CE5A78F783D2573D6ED193A3305A6F2BB8A1D9F53E0152F4F390E94030B33F0D7074EDCDE4AFB5AEE2902D9B3E105999D2572ADFDEB37480F4D6C148ABE81DEB47BD42814BFD99E570DC4DD75C77D066BA1FBF691FB06DAF924541ADFAFC3ABB525151E8067B6EAC9BB738A3A548C3913060B0F697DDB6E78B8A029348D5E76452DC8D766F9CF31986CC93FE8B64DF46F08A43C7D80EF098B294D6409FC4685CAECA0F80D758C89DFE3906673DDB6B1F759F38BEB469F2CA2E96AAF17D5D34CC9D8D6B700056592CFB63BA00A0EF77EB05DF2CFDEAD26846E12ADC4F2E0BA6380BD7761C5C1A8FE090F3B9E4ECE454F22D72495926573F5032B06388634B6B4D0BA7B4C0AD721726A6F2746F98A1C9A68827110C621CDA6036AE46814F7839F65E91616EA6E2B5168CB5A05F8A8F42CC538BD684729D5071CDD7C980891D096DD527D0749B8D378DD2C172CBD2D3BCBCB78AB66778EDF3E16A614B42FD5738476F098EF638EBEEA67F0FD64012663C01392A6384E0FD37386BAEDDAB8F769A1135DA12911624FF7CE4AB4B7D231AA3998052EBA090FC1DEA22B83CA1ECF2B8FEC74824A1554E9B9BCBD5DB58020FCA5FDB4FC5FA75E332BB9C47FDF772CDEFD91A73A89953ADABE47F1CFD52C6E4F250C46A973D577A09FB840999FD2779D2A218796B8D511BA81D9DD435DB55D1ECE517FAC60 +ct = 6613F9DC64AAEDBB25920AA0468FE074C37AA4451C2EEF60D4C8668C88D96208A7B1FA998B42E55CC7A2CAA32571CFD88AA1AC2D76328222DA675D3A6325F3BBA561820B20F8A2530DA78155D73C3991C00290A2A0E4F68DAD53E4578F4D8133C21DE26E6A5C1D0528C6F404C6B6104531C31D0BFCC486BA76A65251AC0E5AE2C58988DF85D68FECAE871173999109C61DE5F6C176561FF1E29C265DEC57E6777753CA5B5D90CD9A441E511AAFBDB5FF1CF3FB90630CA37B5DCC186CF7DCE8EC83DB4367E3D5762EDFBC2529E66ED7E9FBA43FB1C07A086A2659C5BEDA01C0DAE330D32CDB35FCEC8B251757463BCA072E4E2F00AB8091EC30F0B4DDCD6096585EB4877A6195518989C0D7575EAF14C2E3189D2B7BDDA4F59002F82E4566F3E4036A99BCEC023077611641FFBDDAF1C3AC5E4D325B7DB74A72301FF1959418CB8E87B5D3EBCCA44C89BCE645AE73BD699C090561ADE40661D71814EBB816C79C37BAB35867EB3744C90C24968A041928735E2AAB7CD9FD1F160892178E143FD243ECE34AAAE61FCB317691EBAA8A975B09E862BC61E66A06F77F9D5C586A32636B9F3BC9EFDEC0187AD715DF8290E8843394580F5200B66F11421F90358F57561775064CCA47691E16190BCB3A26AB0FB374F758CC1EF64E7E647965182B264953B56F3069AE6BA59E1FFCF510D2D02AB25B8160DE0AD79ADCF82F25BC26869CD2554877493D147CCA57DC44D3822B430F38A90C04A92BD7FC37D37D87567327CD253F7E51D2F6E2AA88856416CC5B7E5A9A6C4EAA87815BACC3CBEAD737399938AEC0528440C23B0FB599F021484E635FE4A44F +ss = 600D281AA7B4FD07967253C51C8628F082C0DC380246C5BEC4105483E2B6D62D + +count = 8 +seed = CBE5161E8DE02DDA7DE204AEB0FBB4CA81344BA8C30FE357A4664E5D2988A03B64184D7DC69F8D367550E5FEA0876D41 +pk = 71FA1AD2142E2FCEC33D9509FF702675060031F94EDA26BA7922F1333E131F5D7754D0E528C8ACCEE369774210D880A1C2ABC415720940B418C001BC7761FBE7AE1D7E6BA935874DB0559CC7EDFBAA42A21E7E0188DFE3D771B7D20C4B453E32A82262DE27827061845BEBF92568A5A62F45F09061146CE8A9D67933EBF098C00D12E00ED492B74D70EED721F85D8E6ECC8F3995FFBE17FA28B8E22DB2CA688698C5D95CE900A09CE156A7EF258E13BF79C17AD1CFEF24EAC664CD574AD17470D221FB7A4579499E2532AC28CA62954E2E8CE236C40FFB2B51B78BC988B53C726775360992F1E232DD7E5280863046DD10FDE7C5EB9C3A5DAF50976E810562AD60B37FB357770CBCFC2316D8682B3C904924540640A9C5CF2B1729C4FA3DFF4C2573108FA20448A565B19386021CD51C2761FFAF4D3F125CAA2A71D3247FCFE00EEB5EC7F32958CBA0F757A32B9B7D3A6C4151CC2BBC7D39D329340A03E553A540FCF6F64CC1EE9C2EB8BB00910F2A75470772D3A3565210D70782C1DBAF9AAF1C34026D78E51F626102133F2C35CDC7A859A1305AADFC8582BC5A2049835282056CA2BA3EBD610A758EE2082A0277512ED2ADD2DC648D66F52B0FF85283E2528342A64EAF56720E33A556D05BB1AE14463A7746BE66896C350776CEFAD010F923D345D18E952AC5EF8B06D000AF47862F394E5586C3A94BA38FB0E2B98313793720B062EFE94A98C2EDB5A17BF1E9E429EA5F6D6FE1DEF27A94EFB232A810056000CFADB12FABDCCAB978E9D7B058B25459454D +sk = 0610678FF4DC3128E1619F915DC192C220F8FAD94DA1943B90AAEC401683A492DA1804DDB5AA9B1C6A47A98F8505A49BAE2AFFDE5FE75E69E828E546A67710049BB97233D6B26DD19845A98D1BABD20071FA1AD2142E2FCEC33D9509FF702675060031F94EDA26BA7922F1333E131F5D7754D0E528C8ACCEE369774210D880A1C2ABC415720940B418C001BC7761FBE7AE1D7E6BA935874DB0559CC7EDFBAA42A21E7E0188DFE3D771B7D20C4B453E32A82262DE27827061845BEBF92568A5A62F45F09061146CE8A9D67933EBF098C00D12E00ED492B74D70EED721F85D8E6ECC8F3995FFBE17FA28B8E22DB2CA688698C5D95CE900A09CE156A7EF258E13BF79C17AD1CFEF24EAC664CD574AD17470D221FB7A4579499E2532AC28CA62954E2E8CE236C40FFB2B51B78BC988B53C726775360992F1E232DD7E5280863046DD10FDE7C5EB9C3A5DAF50976E810562AD60B37FB357770CBCFC2316D8682B3C904924540640A9C5CF2B1729C4FA3DFF4C2573108FA20448A565B19386021CD51C2761FFAF4D3F125CAA2A71D3247FCFE00EEB5EC7F32958CBA0F757A32B9B7D3A6C4151CC2BBC7D39D329340A03E553A540FCF6F64CC1EE9C2EB8BB00910F2A75470772D3A3565210D70782C1DBAF9AAF1C34026D78E51F626102133F2C35CDC7A859A1305AADFC8582BC5A2049835282056CA2BA3EBD610A758EE2082A0277512ED2ADD2DC648D66F52B0FF85283E2528342A64EAF56720E33A556D05BB1AE14463A7746BE66896C350776CEFAD010F923D345D18E952AC5EF8B06D000AF47862F394E5586C3A94BA38FB0E2B98313793720B062EFE94A98C2EDB5A17BF1E9E429EA5F6D6FE1DEF27A94EFB232A810056000CFADB12FABDCCAB978E9D7B058B25459454D +ct = 83668F2EE7D45C6BAA4553F79211F0231A7597A47B9F6BCAA7A753376D6E062C966AC6E66DEB438E9BDE3FC6C6FA016F5FC429663AEEE231C617A5E5EA87AF7B1BECB035BAAC67BDC5CA94445FD8E190A360D06E479609B1C35678D0E8330108FE2B1DAA8358D4B2829D07B05B420C22BFB58FF0C621B9762CA589BDAB799AA7E1639A1F91C5195E7C0FB4F4E03F89E609BF263D33C1D63403012284B613BF5DCF809CD016E6F4ACEC5C620E702E283308B71E962F98A32124D66E3CFDCE9B5F7AF4D77F6B85AB6BC23796D64551512FF1684B9D0C980B8C914F1C1882480799303F4B4B99A9D7279271FF1B5EA9EB2B333D8C1AEF553CD4D1A672979940DA3FCD234E9C4D47207153522F41739DC6B7259594998E62282059599EEA8495CAAB4DF3E1FBC09B349CD1EB84ED4CF37403ADE6615DAD1AD65EADB17C7ECA5EC6FE633AF7656C5AD50D619869CC0F551D0B15288D2CC567F8F7E69EA9F412576593AE306E5ADD7A84021B4A4E9ABD7FDC60BFC483A8B1E7C76861ADC52FBF8E7C221618010472F94A47665D59C01F99EAEEFB2F251D419C58E7557370C6CABB42B10536CB34EB390F2E0620DCA4313EF32C30BC9A1269BC2BB4F7A2F799F66D8202D6ACA252D6AF9C330132CEFC152DEFDA490F2733FF5D36BBBDE6C13A19237471EAE464952CFADB266D47888C96EDD8BBA63612C25B915F895138443D25C050C035626805C4C7DA2369EA5CF2D81AFF4DAEFA0C7BA5E88B2E3BEB99AECC0C51BC5D0A6D78B05CE6F8A9BC722568D78F1A432AB45CE2FCFA39F5EC11030A1472E52627E25C8D6ED274F60A72B11E41DE54E02DEF38 +ss = 4CA2CE6B6EE911DC23E50973C0F4999B7463192A2DF4F4055C519665736BEBF2 + +count = 9 +seed = B4663A7A9883386A2AE4CBD93787E247BF26087E3826D1B8DBEB679E49C0BB286E114F0E9F42F61F63DEC42B4F974846 +pk = 4E10BA91D1222CEF6E8531629119A1D5495B60B3FEC556BEFE1AB4D05273F4F74372890C748C84AC9C202D96F63F8549C015F7D93119DEF9443AC79971A8C3AD1A5F2F038B50D4057F512FE1E7BA80C672383ABB28B6EEFE5AF9B875253C0F2672513F4DB9E2DF8796ABB69571015E35889F8DF4197BE1DB915D274B2C9F7F598C93BBBC8B19AB3FAD37F2486BE68662EDEECCC4D5E81604C01F395E988B04E803178D8305A935D9F5AF69B209B91E6E37C4511FD4F45D7FF93E3601990BA1BF1C274FD8701D0733A802C67F363C33F88F8832701D89ACFDD475D5242EB351B9F06004970A2922A7ABE0D883B9654A1DF5AF0EFFF2918DBD6763E3D50C6E8AC4B9A2B1E5833CC844B416851BC63BA5E209C638F13A8D20191A32F7392937060B9B5B7D736CEA2BB6212CCEA79161A711F2B1D92E88C3D5D15F3A72D292D68A12DEB6987DB2693E18DBFA953228942EE49B852FB376BA93610FFC0C86D1007D3C6C2E4F41485E9439AFD6A52788D21BA73929166A4ED34231C7F95B0042DC9EA81D7D7DDA6ECBC8663CDD3C10335C64BB5E087D73F816634DFBAEA7F642FDEA64BD5D661C9709425742B1282DBF670D0C7536A3A27D4EDB09A6C1643FE748A383547E306632FA066734A11B0CB973D99E34D2864F3F06F2C98DB8DC88D9DD576049A4109EBFAF39117E57AB68E052BC94FF1104D7399120BD8CD8D67B369A77290286FFEE41EFD9539BC685337BCDE41BEFB188BFD89C644805388EA6A8504DF3A1FC68DBE837C94AA7161295801B63EFC4778851 +sk = D322D56D8EF067BA1F24C92492B9C56DF3A6EF54A304ADC1B69913766A1CE69756047447B810CC094D400AB204CF9AE71E3AFA68B88586ECB6498C68AC0E51B936CBCEE9FC343B70CA3795DD04C062024E10BA91D1222CEF6E8531629119A1D5495B60B3FEC556BEFE1AB4D05273F4F74372890C748C84AC9C202D96F63F8549C015F7D93119DEF9443AC79971A8C3AD1A5F2F038B50D4057F512FE1E7BA80C672383ABB28B6EEFE5AF9B875253C0F2672513F4DB9E2DF8796ABB69571015E35889F8DF4197BE1DB915D274B2C9F7F598C93BBBC8B19AB3FAD37F2486BE68662EDEECCC4D5E81604C01F395E988B04E803178D8305A935D9F5AF69B209B91E6E37C4511FD4F45D7FF93E3601990BA1BF1C274FD8701D0733A802C67F363C33F88F8832701D89ACFDD475D5242EB351B9F06004970A2922A7ABE0D883B9654A1DF5AF0EFFF2918DBD6763E3D50C6E8AC4B9A2B1E5833CC844B416851BC63BA5E209C638F13A8D20191A32F7392937060B9B5B7D736CEA2BB6212CCEA79161A711F2B1D92E88C3D5D15F3A72D292D68A12DEB6987DB2693E18DBFA953228942EE49B852FB376BA93610FFC0C86D1007D3C6C2E4F41485E9439AFD6A52788D21BA73929166A4ED34231C7F95B0042DC9EA81D7D7DDA6ECBC8663CDD3C10335C64BB5E087D73F816634DFBAEA7F642FDEA64BD5D661C9709425742B1282DBF670D0C7536A3A27D4EDB09A6C1643FE748A383547E306632FA066734A11B0CB973D99E34D2864F3F06F2C98DB8DC88D9DD576049A4109EBFAF39117E57AB68E052BC94FF1104D7399120BD8CD8D67B369A77290286FFEE41EFD9539BC685337BCDE41BEFB188BFD89C644805388EA6A8504DF3A1FC68DBE837C94AA7161295801B63EFC4778851 +ct = FB194A48F4AE908BE6F0D90E06EF67E6272B23E89473AFCEDE9FBBDA7E23AEE79B8B1111828673DD325CDCD5F806B3A38E2C929637A58E69A1CC08C4037D9BCCB7E0B742610C6D8E814F5824F3F720ED985038AE7806F8D593A0DC2F7C62B3DA082CF00E1D87095C950CFB96E7BFDAF5E83B4DBCE54A54FF30DACA521340AEB698CDED3A03CBA88AEE7201E8261363188BB6354B3125721663FFB4F495D98335B4D5831F4736C0481C784388A4003D0E4958F981783D6E5553AF9C694A7369707C77CE1A7A4BCFF591CF93029724464AA985C6B65FEC057E4DB81EC83D199BF10293F97E6BC1333109798B4F82EFA057C43A50111C6E1AB3BA3EBABA7754E1E884F1B5B4D391B1D91BA95035B10E80990CEC4E507CFCE868BB53E2ACC4436092D259072B4D135893BEFF845E7A3F06E61244B5DFA0CDD05638155D6ADD39B7B56353675C7DA949D64DA265CA708ABB766843921C93638BFE2C78E0D7B1E5BBA09AFA6458C3890AF8EB3574E93A7E2577E42EA06F0D9C454D775127BFEED0267E78BDB76ED8E39D8CCA1AC2D2E32236841A920CE883489DC01768AFF0F9FC2902A2E1F5C7968E4E3918B7171D28E2BF9BE0417266189CE13D61957476A6601C55BE2A2ED1550158C179D2EC004870CDC7F67E4869961DA98493E820AD1F2CC3B0C6C523C615C0085FA3962C925A3322DD2F9A383B14742AED8613543055B5D688BA91DCC7FFF36BA80C6E3317BAD4195E26AA8A01182082AEC8D0C172405760037583619585A34BC3D14B85B2C8B6C02C26B5CC3A24CC95369628E71CA7DD37DA150277327A65A8315B9D4D4CC35DCB575D9E4855 +ss = 0AC4196CED9103213B8ADEA333A872DFB2B029B1B9095E32BC24D30441DC4E8C + +count = 10 +seed = 980D0BA7C8F8B23D0E948A6029FF2659810EA1360064663A8994D0333C8543EE5FF5D6D5C9ACF446E61DC464F792B9D3 +pk = 9C7A58A8A6EA9C2CC7EED508FAEF7DC2E88C3A97FFD9662FE1953B7F9789B51C2C6CE9FB45114A38B2DD928C16D992FA20ECBED3BE866626EDA1C98CE68DA968D34ED47D5162CD9E52E74238409BECB84E05782E59EC7E4264DA23349A699C481E0A05BB41F6BACEE7190EDF7CC8F364B4B78EC1484E749BE78EECA4232CDFE5833085012DA3FE169F3AE6D01C195F2C785B9FD97353B85A59526DD7DBD1743C777EAF4E91F30160763FCC67B8702E90E093E801EB05108C4C414C070ACB0B006C31A2317743A7CB4DD64006D7ABC41CA5922A57A6577CDEF038ED7E5F9A780976A59D1A1034D8A30F5D081A31901B6E120FD1D0B84FA1BD49AB983554448652BAF23E12ABA758DAEDB15BC887765A53707D9AAD9776C1CCFB2D97603736E71511E81C4B4CD518FA1639FE30FDBF36E0836AE0FA2770BFC095C96A0803F40565D6D01EC6B14EDD3822AB262CBBAB2BC0E57218A423A1BBE9FCECE0686F8AB35CE2F8F40B06C116AD69C09E2CE0CC23075D329B62C1853C11CF32A35CE3D217634EF65ED78A65D08751A6F96B3FD1124FB7B97D8C12272468638A02B3988D05A166405106C81A2504B4764CB691435F4FDEB5085C5D5FC70C1B07D57D811E273782413105A63316BC380DB0CF79E3B70B5C2E40368301C23B4298FA813606139B8856809F7A7E25468414FB49448046E127A2CD8CFADF11B92361D7E2038A5E36A6B901B2E420142E883F7BE7033CEDB61911981CCA98BBBF7F20BE59ADA6000F159E0F5FD28B871D96CE002B6AFF5825A58CC238 +sk = 2F1D8A3BEBB34540324B9485FDF3D5BE3B858F544ABC3FC641B5728CAFAB03BA8D6C42E7270EE2B77B6045385F3D175984A0E260363166C73B0C70C97164436326466AD9341E61870A84C6A1C7679F019C7A58A8A6EA9C2CC7EED508FAEF7DC2E88C3A97FFD9662FE1953B7F9789B51C2C6CE9FB45114A38B2DD928C16D992FA20ECBED3BE866626EDA1C98CE68DA968D34ED47D5162CD9E52E74238409BECB84E05782E59EC7E4264DA23349A699C481E0A05BB41F6BACEE7190EDF7CC8F364B4B78EC1484E749BE78EECA4232CDFE5833085012DA3FE169F3AE6D01C195F2C785B9FD97353B85A59526DD7DBD1743C777EAF4E91F30160763FCC67B8702E90E093E801EB05108C4C414C070ACB0B006C31A2317743A7CB4DD64006D7ABC41CA5922A57A6577CDEF038ED7E5F9A780976A59D1A1034D8A30F5D081A31901B6E120FD1D0B84FA1BD49AB983554448652BAF23E12ABA758DAEDB15BC887765A53707D9AAD9776C1CCFB2D97603736E71511E81C4B4CD518FA1639FE30FDBF36E0836AE0FA2770BFC095C96A0803F40565D6D01EC6B14EDD3822AB262CBBAB2BC0E57218A423A1BBE9FCECE0686F8AB35CE2F8F40B06C116AD69C09E2CE0CC23075D329B62C1853C11CF32A35CE3D217634EF65ED78A65D08751A6F96B3FD1124FB7B97D8C12272468638A02B3988D05A166405106C81A2504B4764CB691435F4FDEB5085C5D5FC70C1B07D57D811E273782413105A63316BC380DB0CF79E3B70B5C2E40368301C23B4298FA813606139B8856809F7A7E25468414FB49448046E127A2CD8CFADF11B92361D7E2038A5E36A6B901B2E420142E883F7BE7033CEDB61911981CCA98BBBF7F20BE59ADA6000F159E0F5FD28B871D96CE002B6AFF5825A58CC238 +ct = 8728390D12B3761658764AC25BB768F2C95E5BD30BE9A81CE2F05BCDBEE0394BE1DF656F677719CFDC5096BEAB8C6C4FDB3BCC2135B92D51149C23ED1AF5239905EE00EC794BDF794C02F92ECA364D265E84F5D1E6AE0B759AB842D64341FCA42BCE2927863D5211FA9ED8B01EA91DC5644C13AC8B3A1FCF0F8CA5929F3E44FA43311F56FF8536DEA3027DC8CA0D238651C794D35447B3D9C490D2362F04F534CA0D6135C1E4E84327EA8681A2A67E535A300711B222D6EE761D683E0F96D65BCD2CC488058224CCD2D04946A183EC318A96D4D950BF1807FB925FCB60D06D55778F8C7F53F1A162193D3E03A9DC31FDD83FF6E19D43EDA1E7C643E1CF8315BEBE65B14827E38BC5AF6D2D55EE9FCD32915B26C4EFE1C5DE7654F7B975F91CD32B79AE9E7AD21DAF08F5AFC8161CC04885C550735CB9F9708FF0A5DE87DBAF6C913460A91D76F2A6B1052A06F0235355DFEEB4A93D73F2125EC3DB6B240116C4424FB6C9CD78192B57B2F2AEBEBFFC900BB2DC21D51ACA4489917CF8AE2676145D8F24A5F520A50A8B52E0603B3210A19A25AFB61DB6C98E5F5F2272E668C3F95773DCB822D97976E2704509D1E660BDB88E670BF2B055E0934F8F14541286CF79A6EDDCAC2FCB493D15D5677951850FAF4A9958EA53D7C5A9EA744BB286A03BA3B54E4627C4180E78C50F54AA5A4A5A5E5C8CD37EFD673091528F3195A070DF45BABF46FA4A328A5678F06F6B09F6D0F9712F0DBCA121587D3463BFDDF8E6086732450AF060B248AEC59005D1471B15CD0CC131DB732F1678297A5A536B79AD05099BD3B5108281657A31A48F71AEBE1448D67D +ss = FE8CF769164A3ACB29D531BB06E430386CFA36FEDC4D2DFE4769D738BD0F776F + +count = 11 +seed = 6C029462CA42ED520F10A579F52687101105E0B90C6E7BFA582A4C112B579D5AD0A0ABD38F72ABCFDCAAF5893A112BDC +pk = C0E1706227AAA182687BB5FE51FE72CA158C4263AC370CF176570CAB238A3B8F029EA62E965A00F49EBD9F8577B941E14BA57D8307173F3E526191694A81A25A87332BC44A488C6156EFE40593CE23387EC7BEE5B6617AE9A3AC4000314CFB47A4B52F2582176C74F64EBB6ED24DE7F66ECBB5E76015F92A90D5D318FF1DD442E28D45FAAFB0065636CEDD488DB8346AD39CF56616890FF71178415A050BDA4147270EC989402CA1A21A83492889F6A668BE6E723C00E7E038C1733FFB7ACE332C730BB287898AC6F8BAE8223854FBC2F1501864F23F947218BAABFF0BF2D4044CC52CCEA2D8B97A211F031D87A0AA11B99BC612BB7513575884A04E79C946A3CB1FCD35560EDD3045F7702BD230926951FE7EDA9F131193E824E9591B04DB227F9F16F85DD9EB645A5A9BF68E6A76DD350FC854FF1A29F29D323ABD5CD4A380A688F2907B8CB78FB223C4BD881C9765427612FD8827856FDFBDEFDB665AD56C70744A2D2153F1CC23E927CBD78568292CE1993B7205BC0783EFECB8B3B3C70FB7138050B5CB64001FF924627A219BFC3B467740F62F94847304AF81A8D8FC7752E40868A50F977B22AF37411971AC8F7FFB956669AF0747371075479DBF4431C50C2BAA08A6BB763E2C81335F9D095F4AAF9E76C841461C5A2C67698EF36FCBBD4E78CDC45643CCC79C291B96F338BB365C37B3BF32C64FDEFAC37CAE1FDB949A5F26EA3626305D1FBE7A8424DF624BC9D5FB22711B5DF438403316962CE07D8439196FD53575EB8B405E826AE2E6F85BE88F3E +sk = 31BEDA3462627F601CBC56F3DDF4424E1529C04737EF0EF2AF6D7401F653B8A1812083BFA3B670E3EAF9B443702FB6DB16AC1197656BBD61A8E25ED523B8D1E5D2331859E2A7B4F3F9858D9D97F7C703C0E1706227AAA182687BB5FE51FE72CA158C4263AC370CF176570CAB238A3B8F029EA62E965A00F49EBD9F8577B941E14BA57D8307173F3E526191694A81A25A87332BC44A488C6156EFE40593CE23387EC7BEE5B6617AE9A3AC4000314CFB47A4B52F2582176C74F64EBB6ED24DE7F66ECBB5E76015F92A90D5D318FF1DD442E28D45FAAFB0065636CEDD488DB8346AD39CF56616890FF71178415A050BDA4147270EC989402CA1A21A83492889F6A668BE6E723C00E7E038C1733FFB7ACE332C730BB287898AC6F8BAE8223854FBC2F1501864F23F947218BAABFF0BF2D4044CC52CCEA2D8B97A211F031D87A0AA11B99BC612BB7513575884A04E79C946A3CB1FCD35560EDD3045F7702BD230926951FE7EDA9F131193E824E9591B04DB227F9F16F85DD9EB645A5A9BF68E6A76DD350FC854FF1A29F29D323ABD5CD4A380A688F2907B8CB78FB223C4BD881C9765427612FD8827856FDFBDEFDB665AD56C70744A2D2153F1CC23E927CBD78568292CE1993B7205BC0783EFECB8B3B3C70FB7138050B5CB64001FF924627A219BFC3B467740F62F94847304AF81A8D8FC7752E40868A50F977B22AF37411971AC8F7FFB956669AF0747371075479DBF4431C50C2BAA08A6BB763E2C81335F9D095F4AAF9E76C841461C5A2C67698EF36FCBBD4E78CDC45643CCC79C291B96F338BB365C37B3BF32C64FDEFAC37CAE1FDB949A5F26EA3626305D1FBE7A8424DF624BC9D5FB22711B5DF438403316962CE07D8439196FD53575EB8B405E826AE2E6F85BE88F3E +ct = 6DBE96281D66F1995502F15926640875E7CEE6228FA219B14D74C7641FC599AC305ED53D74AAC134A8846E05059C9A2918BFD6E7FA6E970E1E83609726B3B19B0FD676AB7F9099222A0A75DCE6C4711B3E6142F9CF6E8611B0ADAB1213133D8E72B8D32D51E0F307D1AD720737CC8DFE4AF5D24C0716C8E1DDEB695165DFDFC0ECDAAAC32A9A9160CEEF450EA473C911479457C0A1FD0E5CA30E4A31DFBF0AC28C020419D23C2186FB2A7B8AF5F10632827ECE4389F8534B0AE4A4443BF730BD243ADC63205E7FDDBC36DDDA1115CC829ADA03F157026435C636A3AF109338403E44D8FDEFDBE5ACC269FF8202F142BD48BD9F7019156F532CF22B0740339542E757248E7D616D1CED4632D8A5F8B3791E9D303B5C9A7CCB933F0B8A6D3FAB10B5BB36DD43F4A37B0C04A1EC6DA2BA58077670C815249527ABDF75A067479969B817ADDDA75ED9EBC537E9C55346BA981CDD5DAD7A0327B60570D39B98883FDC8EAD3BD88992C14E8E4AE0D2268CDE8F1FBCA9077956113DAEA6D9B0163D8FF843240CB3DC37DC62D8200BC42D2652A04BF91D1F263CDC8B5FA7EB63D912F837727BD926CC35011E2285E83B71EABCD0381CBFC392901F11EE34F130D273A660D85EE3D26A452288A6F290B7349FD62748D7E09AF25AC8292CA71BB52EDB53D3D1034E76201FB44F4970109E1460B80F10F62FC52DEF366DF24FD2C2E41376CE5C83B83E0EF55D4EADAAFB3F187B4785877B591697612506FD634709A7E1B38C66598477AC1134866F1DDB2D008F747FB55D97570D1D7D09C36203CEF2607BE3715BE72FD13DF384C6056846C7380BDCE7B4F245 +ss = 5313944F9D23D149C82725924F10941F841755A508DBF62D937BA7B5AB6C2F19 + +count = 12 +seed = DB00120937570D62331F4C3F19A10465231EFF46465CDEE336A0D46AA1E7493DF80F18617F9FFD0476CF7784A403EF4F +pk = E486F95A900785251E9701A98CE265F8DADF0CB4F278779F1A3EE5189F6725E22B63BBF50F83C4B028A49115C7B9C8AE21E06D4E4752318B7E9D3C951C0FF5B5378CD2FE2B1E3607233E0F78B4C6AE795B7B2EE27A940DA53513D006BE57403998E257880757419506778F7BD6C2E1657BC59408D15D70570E82F5F2ACB1652D64DAA68353803CAFA569297260C80D2709A6179C1220AF98D26F1A6498DA56784B112A8FF05B58881D8F17B9D50808E3F4B35DCC86F95B75D397C66A9C19A51083ACBA34FD6D21C5B871B89357015077E0DDA34DD6331235F162860EB4FCBD11ECC8AE23D50626EEEFB53BC220923F180ED3DC6271FADE8FABE5A057E1C6E01DFD421EB166C1D4571853C5CD40C39C753A08B9074D3F8A824C4B53BC48D661B03D34582389257B5F198680F73F5B7F8350F765990BB490E8FF800944388B187BDDB35DDE70493E873493085F446B0D87368A0F8BBAF9D9EBF42370927339068BBB7C0555C47C894DA5659EB7D6D3DB5E7F5F3AEE2BDD432D6969D8E8FC6720CBC5CD956DDAF4EB7E1C4A6E777F6CFFB4E4742C71B25B82A36A6F978DD8CE8A8EC2757ED17521E38215C71DB6159235F83BFEA2693F1A12F5A7D1E6516E8D4E18D275F7DA27626C2896D620E49F2767ABB56FA98C2C051130E42ACBCEE8860E05991E25CF865B55ACED4535EF74ACB6BE8BD104A5F8396B998885BF1738B042BB61F3D14433084944A21DF135013F00ED02B0699C03924FDB027F3B38B9269252E1044E09B529582DB86F4993589BB916447C063F +sk = CBDFF028766D558AF4466EF14043A1A9CF765F7748C63CC09DCEB59AB39A4E4D8E9A30597E4B52FFA87A54B83C91D12A5E9C2CD90FCAC2C11B3A348240411A4C555A3DEF09A64C09E9EB370293203E03E486F95A900785251E9701A98CE265F8DADF0CB4F278779F1A3EE5189F6725E22B63BBF50F83C4B028A49115C7B9C8AE21E06D4E4752318B7E9D3C951C0FF5B5378CD2FE2B1E3607233E0F78B4C6AE795B7B2EE27A940DA53513D006BE57403998E257880757419506778F7BD6C2E1657BC59408D15D70570E82F5F2ACB1652D64DAA68353803CAFA569297260C80D2709A6179C1220AF98D26F1A6498DA56784B112A8FF05B58881D8F17B9D50808E3F4B35DCC86F95B75D397C66A9C19A51083ACBA34FD6D21C5B871B89357015077E0DDA34DD6331235F162860EB4FCBD11ECC8AE23D50626EEEFB53BC220923F180ED3DC6271FADE8FABE5A057E1C6E01DFD421EB166C1D4571853C5CD40C39C753A08B9074D3F8A824C4B53BC48D661B03D34582389257B5F198680F73F5B7F8350F765990BB490E8FF800944388B187BDDB35DDE70493E873493085F446B0D87368A0F8BBAF9D9EBF42370927339068BBB7C0555C47C894DA5659EB7D6D3DB5E7F5F3AEE2BDD432D6969D8E8FC6720CBC5CD956DDAF4EB7E1C4A6E777F6CFFB4E4742C71B25B82A36A6F978DD8CE8A8EC2757ED17521E38215C71DB6159235F83BFEA2693F1A12F5A7D1E6516E8D4E18D275F7DA27626C2896D620E49F2767ABB56FA98C2C051130E42ACBCEE8860E05991E25CF865B55ACED4535EF74ACB6BE8BD104A5F8396B998885BF1738B042BB61F3D14433084944A21DF135013F00ED02B0699C03924FDB027F3B38B9269252E1044E09B529582DB86F4993589BB916447C063F +ct = 06A4254ECD625472935428F20886535A261AC3278760F234033AD2D1C6FA509680C34C0560F4A34B979BDB611B55B4850A2D979CF0B3C87626EC20908162A315D261904C39C5E87651AF92E2771A81C80236D3C30FC333C8545C64CD0437460BEA0E558E43055A6E183D05208FF7AE18EC69220F6585EA9C5EAEBB764A22DC50FE36457793FBB844FC7436D4EE663CA0CECB97215D4D7C89A7CE53073DAEAA0A8B496EEC4F41148EB00E9AAED85BD69CD763B50CC9A7C0B5F4E5BA2DB0625DD9CEC5DE46EB4C2EC829E596F395B1A51CBCEEF2256A84208405648E3B8C1319D2DD25E55BD4CF89D1D5D5F11C025B9EC94A23EA2E702458BD4E1EC5A0EA1620CC7E6F033F72E69112021F9701CDB54987EF40EB211CFE5CD1D4684E6C4583A3E8E30411E4B44941295E1D1B67CB332A86358734E38B53BAFF7F8B8BCBCCCE8E62584DAF92F8ECDF6C2CC72EF897A2DCFF4C5AB0F4C3E026E6EA76E898E46D4F424AC6973DAAB4A7D837AD9115A4371E886FCB6B3BD94FB45DB3A6FD6AF491072DE556774F3D01C600AB91EEE07ABFF7D983F60E76782795FF035D219387089D1A17C1704241373E1BA0B0DFBC057CE3DB4CF1C2C414E76D81CC12D6A6DEB8CC7E5BA041B8B62AEDD88A403B945E96CFE81E219DFEB46E580C5FC9B5684BC73D57A7C0DD442FD3FE2135DABE8B8E7ACBACF05DE15654BB6B1AF6DB46AC039FBB594AD09F9944F66A08B9576B9C58DCBE0BB16EA90D5A5A4084A483869EC2B43B2153A5EE679C0A4E23713E329090F58ED4F29F2A3CCBF17E7C55692AD4ACFEB89B4CF909645DAE5BF0091A9A162B9E1A86C328CA39 +ss = 7961DE81F9C4303484CE85F5EC4128D8C211A7CEE8A3821D5CC391DCBAEBD42F + +count = 13 +seed = BD26C0B9A33E3B9B4C5D7EA32D5BD1FC371015BE163C86F584E49BFD5362C8D8341161CD1308115B2A03B7E5EADDD418 +pk = AF0F2D51A5A0AAA59F619B8F7F0B0436714E31DA4DE0C54352624C536AD59C9B23C95DDEB2DDE00E889936EE8701D4C545E2AA1FBA31B1E5EB71A6BFE3EFDCE0B95F6787EE16FA966011F59CFC9E4851B32293E2B790AE6CD2B85CB4B06F7D231412EF8C045ECEAE9DA7AB62452FAACEB572E3D1DC110A765B59CDE681174C79AB16DD039D9680D1643A8CD24CAB1C5836C67099A2FEC99689E4586C212269A645363E8402FCAECC43F8EDDAB2F5246BF4F481886ED09A7AB7041A19BDE915692FFD1B2F6E99B3F50AF9CBA70CA73673864194E851D5C5AA015E081A79F37D6C1AA514EE8469FDD1AC462E2B3079E080D2FAB8BBCD6EF87D27225C1A0A68C626E21516AAC5B0C1930E2C22EA34F39AF0C9DAE4540E5F88BD9744D5A43EC8BF512DCCF140E3C1936EE45C258451483420B0718D20F0ACA50A3CAE891B61ECE248C86858AA9A6A95FE8868ED4424D17F024D0259E6FBB66B3DDFD0B8AA566AFA27B0BF930ABDBEDEC9F89911FAD5F305A3E6E9D011A2897552B03C67C145D7422D142A0CC643DBD3074D2CDBA0464DDD25E0FF9313654081479BADC15F4FA705B00A372D7BAFCD8BB5BE3BAC4B831CE6A401E92E4ACC4469EBC8B1E008EC3D0FDE202AF0F3B0557B6A1360FF1B803CDDAA10E89FBD9727A4CC5161E17F88923A5E26362BF12C933C3534B0CE54BB4907ADBF08A69E9DD0D388F896BD3A2737C5DDF3B50C8E0EE9BA2B683CA1F969DC3B76514E9271283292BADE432B3AEA0D7D2E50012B392722C1900023279DD988F06763EA0F17 +sk = 4C04310BEA66305C6CA8BA6B8F61CA96257A67663AFC11761F13FB5C7B324B6B8AEC87A9A79204CEE2986867A2906EB851B734B8B22B91D6749B1A5F07C44E3B8F1862A59F55A7C0859D28B7F2A8E703AF0F2D51A5A0AAA59F619B8F7F0B0436714E31DA4DE0C54352624C536AD59C9B23C95DDEB2DDE00E889936EE8701D4C545E2AA1FBA31B1E5EB71A6BFE3EFDCE0B95F6787EE16FA966011F59CFC9E4851B32293E2B790AE6CD2B85CB4B06F7D231412EF8C045ECEAE9DA7AB62452FAACEB572E3D1DC110A765B59CDE681174C79AB16DD039D9680D1643A8CD24CAB1C5836C67099A2FEC99689E4586C212269A645363E8402FCAECC43F8EDDAB2F5246BF4F481886ED09A7AB7041A19BDE915692FFD1B2F6E99B3F50AF9CBA70CA73673864194E851D5C5AA015E081A79F37D6C1AA514EE8469FDD1AC462E2B3079E080D2FAB8BBCD6EF87D27225C1A0A68C626E21516AAC5B0C1930E2C22EA34F39AF0C9DAE4540E5F88BD9744D5A43EC8BF512DCCF140E3C1936EE45C258451483420B0718D20F0ACA50A3CAE891B61ECE248C86858AA9A6A95FE8868ED4424D17F024D0259E6FBB66B3DDFD0B8AA566AFA27B0BF930ABDBEDEC9F89911FAD5F305A3E6E9D011A2897552B03C67C145D7422D142A0CC643DBD3074D2CDBA0464DDD25E0FF9313654081479BADC15F4FA705B00A372D7BAFCD8BB5BE3BAC4B831CE6A401E92E4ACC4469EBC8B1E008EC3D0FDE202AF0F3B0557B6A1360FF1B803CDDAA10E89FBD9727A4CC5161E17F88923A5E26362BF12C933C3534B0CE54BB4907ADBF08A69E9DD0D388F896BD3A2737C5DDF3B50C8E0EE9BA2B683CA1F969DC3B76514E9271283292BADE432B3AEA0D7D2E50012B392722C1900023279DD988F06763EA0F17 +ct = CE3F1D6629D7BDA4A70719AB3B49B70D0F1BBA52F373D0F0A817D5CAAB92FD71A8A6A636E62F4ABC4A7B5B327F34AA639E4792D967A6376B1E1002C57B716533783FC6A5937D691006E6D8452BDDE93819E72C56292F97D84E525505D535B583A49B2A8E02DB132B432A6E2C17ECEC1CE070145B0AB6DC899FAE618CBF12E57F8F5EE82A067CCC47F63D0A5BBD313C92894AA31CA6CF83336DBA3BEF74A014452D98C9BE8D2475944879CAD774E4A4809706CE53DADE449AF63F653F659914E354EE0452172412AA7E872D72394CF7D8ACA0A12ACDC92F3AEB573AD759E2301C03280B2B313FE779EF3D1863A2DB7590797CE264A08141044EFDF428709DD2EBE6109658E3A4EDFBBCAF8546187E4BAB619531FC7C7DBB53F056E9CA9EBF01114BAFEE3CEC08A4B90AE7CB406D5FD92894675C1BF1FE1A14D31C253CA69D9B0C98A2E62B49F07DFF34A611614AAFBF574DAF3EDD0EA4A2ED6C8838038D1026EC97B09B76E29BE3FE2BAD084EB6CB846CF8CF59A2200CCC5B7A4FD0332E02DFBDEA5539AA03851DD3673688179EC8CFD5114A832F0AFD0D5CAA8BFD8662A612118A2F08C393993B97BFE13B3DD6CE8E609D2568A1192A52C01EE2153C54EC12427B761A8DC2E646111E8A3912537AF3DC1B434FD8B516735A30DE167EF58C40BE29F0970CC75241198B6E9A99FFE65C5E58FC045DD4E9EBAA756E0E45DF94F8977BE6A8D6D0A92483CD62DB5F22FD62C35F09AD21BD09E96166013FCA83BA98D1B813605E61544B90BE1518259B49066313C7E1401CB4D7CA2F6F4680E920F659FEE5AE698280EC29C105EB7822D900F028E3C6A7 +ss = BD7157664183C42F6DE8C8707071C4E731151E9327FAFD536C634207DE2BD4E5 + +count = 14 +seed = E2819EF86853BCA1B9DEE7EE1C1619988964F9A913E635AACF0D96CA6E0300D084329DABD8F149E24176D22757404260 +pk = 6DF986F5E8ADC7F0DE157900ACC1ED39337970897D0D2DE5D1B22D7658C7A4E0C7D6E7ADE1A90E18F4B16C5A536470D19BD9DDF2BFA5E597A34DC469FE4D9FB21306AD00B8FA1237B0F6F2CA2DDAF476EBF0F7F8A066D3A6A91321BA025ADBB417E310D49083D83ECFE1CEE408FDFF7AB94555143001ECF38337D95EF7C5708C66AF4BCB95CAE9E77AE0E8C38B3EB45A55B422CDD732C19B722F2FA19F7F33E5F42F959A1AA7C632AFE463C98774F9F1EF3F25749BE740C81F10865C36F119887ECCC263F2749AA88722ED244EA51B28E0A04B0FF67F519EF9EB90867EE2EDD35960D5DD0A23687CBA1C3B712D72D6D21E8AB4A2E6BD6C6403BD99E3138D298CBFE3ECE1C2281660EC828C6071A417E8AC14289A992505BF8D1A9DC80330B778CA7EACF08C3225A2672FF04673BAD08AFF71B763F9AC1DD852C82A520A942941E120D5CBD84C4F9A233CBBA23083CBC2987DB711586382C642206D3D0656986657EB331443DBD94AC04DA7BFF89B9D160EEE5EC1183BBA2B15276D778F756A1ED572702BAA5A35DB697AC7C5D6BF2D7FE619EED1A9140CF2640407E69F69D99D076F620E389FA7D198DA7CA35CD2B21FD98DCEB5C4DE7A0205DEDAF1AFCFACA456E6B4E1CDEC8539589D58FF2F11515D75E57C2E3A55EBA40EFA13EA948141A796D3B11ED4CD95479066A2C9E94187762C24DE36733CC289894A7B183D206B4F56A86AFE4CDCD93DFDF301E37D59C489663C2952A8A7190CAE7D4CFF853A5AE3FDDA6F3AC7C0284E6C50853AB56A450B19D20923 +sk = 38A0D5F41D7DC1896EFD1B45B0485634CEF149828751B96087A0A6DD81B4D58AA2ACF359556DF4A2ABAEB9DCEE945829BEB71185B4D6BD18B76E5668F253383A0A0A185738805628063B48C2EBE37D016DF986F5E8ADC7F0DE157900ACC1ED39337970897D0D2DE5D1B22D7658C7A4E0C7D6E7ADE1A90E18F4B16C5A536470D19BD9DDF2BFA5E597A34DC469FE4D9FB21306AD00B8FA1237B0F6F2CA2DDAF476EBF0F7F8A066D3A6A91321BA025ADBB417E310D49083D83ECFE1CEE408FDFF7AB94555143001ECF38337D95EF7C5708C66AF4BCB95CAE9E77AE0E8C38B3EB45A55B422CDD732C19B722F2FA19F7F33E5F42F959A1AA7C632AFE463C98774F9F1EF3F25749BE740C81F10865C36F119887ECCC263F2749AA88722ED244EA51B28E0A04B0FF67F519EF9EB90867EE2EDD35960D5DD0A23687CBA1C3B712D72D6D21E8AB4A2E6BD6C6403BD99E3138D298CBFE3ECE1C2281660EC828C6071A417E8AC14289A992505BF8D1A9DC80330B778CA7EACF08C3225A2672FF04673BAD08AFF71B763F9AC1DD852C82A520A942941E120D5CBD84C4F9A233CBBA23083CBC2987DB711586382C642206D3D0656986657EB331443DBD94AC04DA7BFF89B9D160EEE5EC1183BBA2B15276D778F756A1ED572702BAA5A35DB697AC7C5D6BF2D7FE619EED1A9140CF2640407E69F69D99D076F620E389FA7D198DA7CA35CD2B21FD98DCEB5C4DE7A0205DEDAF1AFCFACA456E6B4E1CDEC8539589D58FF2F11515D75E57C2E3A55EBA40EFA13EA948141A796D3B11ED4CD95479066A2C9E94187762C24DE36733CC289894A7B183D206B4F56A86AFE4CDCD93DFDF301E37D59C489663C2952A8A7190CAE7D4CFF853A5AE3FDDA6F3AC7C0284E6C50853AB56A450B19D20923 +ct = CBEF4A9BE4DFA3AAF49DD81722C735B6E50FD3B8844E8D47324EC3CDDC47E8EB510E26711A4A188ED0C803FB3AFE0DF8DCE4CD2E43580FFDD1C048DB24581E4F7045AED1D42FF733BBC3347B95FDF7AC568B658A455AB47D6BCB076D4D07E7940E161DB92505AF3BD49BBDF6FB599759D02890D88236DA21BB7BA20BF4811ABD64DBEFE71405E3DB0B6BB0F51444D7776D86D31B48000B52DA4E3362591804CCB9DB36FB9A34D4AAF1FC8D5741A93576DEB4C07F6B7F384C165187136BD7BF8F8A2688CAA3D43639B76DA0F39A4CA37914948E0504DCB07396ACD7D0297BF7C3FFC0486C36E36DBF21C9EB75FA29382AF796F69B72DA75776B605DA944A72B01F46FA824E498A8CAF1D30E97DFD2038502808077762CF52CC026B29FCD977D391C1C226104C625903C95048842C8D5AB7277BE547F6EB13E25571B8A92C67B4C83F429A78F59F3D04EE983B8C850F358682FC590BE392C996B87A1E93FA495B25525CEB284B986235A4C1CC41F0F43804097EEFD0467341F7E45DBD23F0FF0AEB400C6E2F9504F35DA5005AE9F4BF1A080A9986DDD6477CB753B3A2D1557CD9CFFD360AE99B78FC6A4F465C66A80104A27B4FAD0B1CA49D3E6DEBF7DC31677F1A1DE29C8F1393AE0641AE5E700E5855BBBF10AD3E86D62C6A649B9D9D57AA0AEF171AA6BE37297092FB26469DFC125E528A8F4B5B9A9803F2AF58120C4E17547E067D0756ECC60064C1E7C605F9401EB75A81660515D298C7FC2DE7CF42262B831F691D04A3A614F992D094F1A62E2D846F3630CF26936F4BD17C3BE01E17A81883AB3377ABDF1AE892E745B8A4B0DEFF9F99510 +ss = E52C1D2BEDD3E134DC03578F9D427521121B98F7954E97EE50A752F30D1ED7C4 + +count = 15 +seed = 669C4EF8A051CE201DA65FC4BC34D398EC1F806276FC5D987AD71D93BC12DC8F107B58BE6E8422A0795C88CB9A0E7488 +pk = 9DEBCEFFD1BFE934A2D24AE3BF61EDC788E4617CAF342D5BE9E8995DB446F4ED577A5D873A92A9CCC71D67E149804EAE541CDCAC026F2908BAF0A02BA5117A72789F9BCE83CCCB22F694524E2135E76BFC0BDCA7E6DFCF22F1C51C778867ED35EC84FE21E5C1D387D5CE0EC6FDE303BFAAEB5FA39ED38A746B0F8BE64F12379417002046536E9EB419167042F15A60E5F9D20F64FF17285D650F56E6A9D5F849D05495E05CA20D899BD1277FB998561927C49FD1BB7F8E21A2ADF3632CA033B5DB127B2E50FEF7AC6C4C1B12D8918167D344DDB512ED68C1273F77BB321023A47DDF51EF28239FEA55BE4608476911FF80983FFC468A71211FD61A020D653F106B38B1FB35DBB724B4CC1F2833156A2FA3D1D66E017D9AF5C42C411B0D29782C9840CFF6B738FDE7C3F4E1FC016117351DF9989586E41CEC190D85576790FD4A357830A56AC0B96919298CF0C5F495CE6954BFAA9AF111F9719164ED459ED4F16CDC6F8960B5E9F6023D89B3B4E456F613154D0DE68EC22DDA4098625FF8A92742EFE8F9232125AC4A7A766C844FF3029B83EA9BBF51FC051FAD92C16B9333D0FFFD758E70A8C8C2A37FACC2BDF9A5805330CA762254737F6D7294D2C805DC0D92FE2330DF07C7E60692CF57AC9293A0CAC9ADB22B3E70CF5CB1F5E292CABE763BCE29A98257896539205743C49BFAF3F9C93812907AD1549747AAB10A96E25887E43DE4B3AF5D5175B2CE86AB17739922B965E0422EC0EE4FB3E0B53C38A14E873A2B8C986DA1A2D7F8B479285615D5E2E9A51A +sk = 97B5665676E59E3538EBADAA8CD50DF1F9FDA1502D9894C616A946078E56B621DF05318B5F655EFE36F1B678CF4B875108A18DB2FA312261CAF839F84BD956C55EF849036D6447BEDB6010EE65403B029DEBCEFFD1BFE934A2D24AE3BF61EDC788E4617CAF342D5BE9E8995DB446F4ED577A5D873A92A9CCC71D67E149804EAE541CDCAC026F2908BAF0A02BA5117A72789F9BCE83CCCB22F694524E2135E76BFC0BDCA7E6DFCF22F1C51C778867ED35EC84FE21E5C1D387D5CE0EC6FDE303BFAAEB5FA39ED38A746B0F8BE64F12379417002046536E9EB419167042F15A60E5F9D20F64FF17285D650F56E6A9D5F849D05495E05CA20D899BD1277FB998561927C49FD1BB7F8E21A2ADF3632CA033B5DB127B2E50FEF7AC6C4C1B12D8918167D344DDB512ED68C1273F77BB321023A47DDF51EF28239FEA55BE4608476911FF80983FFC468A71211FD61A020D653F106B38B1FB35DBB724B4CC1F2833156A2FA3D1D66E017D9AF5C42C411B0D29782C9840CFF6B738FDE7C3F4E1FC016117351DF9989586E41CEC190D85576790FD4A357830A56AC0B96919298CF0C5F495CE6954BFAA9AF111F9719164ED459ED4F16CDC6F8960B5E9F6023D89B3B4E456F613154D0DE68EC22DDA4098625FF8A92742EFE8F9232125AC4A7A766C844FF3029B83EA9BBF51FC051FAD92C16B9333D0FFFD758E70A8C8C2A37FACC2BDF9A5805330CA762254737F6D7294D2C805DC0D92FE2330DF07C7E60692CF57AC9293A0CAC9ADB22B3E70CF5CB1F5E292CABE763BCE29A98257896539205743C49BFAF3F9C93812907AD1549747AAB10A96E25887E43DE4B3AF5D5175B2CE86AB17739922B965E0422EC0EE4FB3E0B53C38A14E873A2B8C986DA1A2D7F8B479285615D5E2E9A51A +ct = A8CFBD5F62B4E10A83682BF369C76C262C6F514689D2FCD79D0D598C35BDED17E697A9A373BC4329293687AE43BA0C0C757AE0AF86DF9695EFB2ACD23ED1045F03DE4D95C94AF5D14A2675A5D073248CEE0A3C7758008F9D061BC4869A2058DD26F10CD443E4E90B8CBA66E6241EB065B481A07D94129682C794CB01A2FBD7992519DC1DAA5B161B257C1A7D40D0BB74108D418F14BABB625F416E8A2FF2CAA739D6AF60E08BD2D763D79C7D2C075E30A38BA4DBA581106DAE854447D3038767BD67E2E20A0917179A6003F3318F43CA7B60891E7BD6B462A023DCD09D4B8C3360D102141A0F79EFBDBE07AA6E4DA5C4A56D9580E32F1B634033BCDD861931EC5EEE747779B6113E73D310EBA3F5D69FDE05DD43E5F1E7D12F1EADC61CE8CB60CFE98CA836B3E7D66B63924CB2F96E084FA36C1041BAFDE398DBBE0408C45F01796C39566463DDA78EB6D980674224C1F8299AEE7250E32EEB975D53145875097EDAB942ACAFEA3554928E9C2D3F46569CEB3461128D55166FA2DD3F1CADCAF2977E966D0382661BEEEBA408A90AF33A716B28E3F814A8ABE41208A815360F01E2183A7134F321C8039083B2B3B1A2BD7DF11F7B58524D6D748B2A73ADC0B7F8211C975C3625F0F768F40F0936C38027717AAAC2481E36D989371CF68ABA3FD6E1E2FE4ADED7C920DED0163664DBD85CD73E8C97DA6CE7EA744D833857EB740A79693F63EDE69058428EB3B69DFE9EE00A01C58DCD529284E7C50B382320720A25335730D28C2BF164DAC56B5CB7C2330AD83C3548F163D4DF38E2F19117918FFD83962423B16C23EB536D7F59CA9C4A7AE81933 +ss = ECA5B827963949B33CB9113F7C46F82FBF1B457B50CECF17D436328B9A37D9DB + +count = 16 +seed = 9DEBCCFE818F6B5204DB4EA09C03EC9A19DCF1629C1527685B8A29776BB1DAAEC45F8ABF8F0ADC9A8C8BD6E2DF6D8048 +pk = EAAD1B28CFBD736B988B8CE312D45BF9EAD403612012A232A28041533E49C698FC7727C90D5C7F33E772DD88C54086F492DA1231792A65D79EBA5CE5302976B1E451F19217A2D18C3C76E6A42DD30167B3D52C041539D6924DACDE682D2FE96329C785F54DF4F3821E75E424C8E27EC058F91FA27F0FEFB8A5F666B34A8B050C96833F2BE9C9E892F3C97990D04EA934F7DD04632F5B7C71ABD3720CD61DF1511A4D85C794C33B7BBA49E3FDA965AE4996B61C9CC93F23CF165E7C18E963B54344AF9BAED76FE8C1BD43053A335E453FD6FE2E037CB0C625C5F7D3D27A44D5438010C298586D9AB83C7EDCDA443D1956CC8B2F2E9767EE61D694AB1E6F9A391D363FF87192525341AF252EDD2F028800AA9DE163C30EEC12372EE7D9A9E31E409817F1865F6AAF13EC9EF9C43DA0DECB3186D2EE7A096E2F01FD8E7BE12C12A2D030604527739F0859E79D267CDEDF972F91950AF101408AB68072D76E180478BCD3BE60D4A63680BDB0AF151245F82011B0C922A82495553DDDEDBE3D112116CF9D4717F3C44381C1CAAF1DE147B3C15B6057A9E8824BD5468194B437A09CB04849B385BC0DA69F1AD093BD5312DC8D2EE7246188F62A4579DFB483CF9FD06328236F2B78380E2393602B7ADE11E42185C8175F8052536CD8C089E352C28B40C905B7643E84E464DA3B629B732D6C7B88B05A3669B13961AB60364239323C8140887071B1D780090749DE0E42190C7C4AC8984F97816408DE7BE20FC862E329AD28FDD5FB89AE7537451B2A20BD838E2C36C012 +sk = EF99224A03A85A46EF115474EC5B5D620DA6795D6EFCCA4C9135D19958A9DE62DF7D92DDA83E6B2EF4CCE08C9134563063068A196D7B1A1A13623E48AE12528E90150F7F22A2EFB276D6C4FF6DDAFA02EAAD1B28CFBD736B988B8CE312D45BF9EAD403612012A232A28041533E49C698FC7727C90D5C7F33E772DD88C54086F492DA1231792A65D79EBA5CE5302976B1E451F19217A2D18C3C76E6A42DD30167B3D52C041539D6924DACDE682D2FE96329C785F54DF4F3821E75E424C8E27EC058F91FA27F0FEFB8A5F666B34A8B050C96833F2BE9C9E892F3C97990D04EA934F7DD04632F5B7C71ABD3720CD61DF1511A4D85C794C33B7BBA49E3FDA965AE4996B61C9CC93F23CF165E7C18E963B54344AF9BAED76FE8C1BD43053A335E453FD6FE2E037CB0C625C5F7D3D27A44D5438010C298586D9AB83C7EDCDA443D1956CC8B2F2E9767EE61D694AB1E6F9A391D363FF87192525341AF252EDD2F028800AA9DE163C30EEC12372EE7D9A9E31E409817F1865F6AAF13EC9EF9C43DA0DECB3186D2EE7A096E2F01FD8E7BE12C12A2D030604527739F0859E79D267CDEDF972F91950AF101408AB68072D76E180478BCD3BE60D4A63680BDB0AF151245F82011B0C922A82495553DDDEDBE3D112116CF9D4717F3C44381C1CAAF1DE147B3C15B6057A9E8824BD5468194B437A09CB04849B385BC0DA69F1AD093BD5312DC8D2EE7246188F62A4579DFB483CF9FD06328236F2B78380E2393602B7ADE11E42185C8175F8052536CD8C089E352C28B40C905B7643E84E464DA3B629B732D6C7B88B05A3669B13961AB60364239323C8140887071B1D780090749DE0E42190C7C4AC8984F97816408DE7BE20FC862E329AD28FDD5FB89AE7537451B2A20BD838E2C36C012 +ct = EB5072BA6A89BD298188559BA0A9FC3B57E1B2975811DD289229A1711F0D43EBB8E9A290671CBCAA6E7838503219ED4C23C333E3BA47B975FAD63959BC88BA500728AD4CC1710B61E8EDE5FFA269363A01A6FE58FA9A377FC04CC6C4252C7F166A1A52BDC73E892EEBFA44C221DB67DF9A1169F98DCE31372BBE39D41417DAA5E6716797989EBD5C76D701ECBB8F36DD95266450B472094C3134793EC4D65BA67234D9BE3EB329C23B64F8D627518890CDE983E84A3BD276B3385B1C729723C655279094B0B66F3209DC9F7CA6FD3D18C1698C2EE5E31888CEB41A8AEB722D74B34F770E0C713B460F2CA8682BB267A17188D6A07AE5599159900BD8D615F3BCBA2D60D746EBEF73FC08542AFA491B104AF8B4B50D1EB49A5631DF623457837FD7E1915D4686473D8F3B92094E77F61122FD0B95B38C5A2C857BABE903C35307F504908ED8A20ED011AB5A824FECB0733F80FBEE36E001CEB138DBB731332315201D7E203A5B15A542B5F5A6C31676FDD864ED725986863F6A57AE196CD5ACF8CBBA281BA66807DACEF4D195E36D6E3E173FDF754F043D1D8BEE0D07FB55A045B4C5DC8DC4D42BF2D550B0A8048CDB93C45BD0742064C3D5189D4DD79B9461A83DE45CC3CD2171F23A3C17EF65EE71A9192A4081AD2C7FCD1F4E107602423AA47DA4555F7CC657B8449FFC31BD8B103571E76BBA0F7E72483D73475DE002DFD3E2A3E15592B4E9E908C7FD7B3EFBDD9C6D95FCBC697F44DC8EEB654CC24BD770067D4B42CDD4CBF639805EA40618DA69C7EEFA67C6EC7F4830A210421D17D2427E990CE31DF5DAC44D0C12500131E7B11F7A7504 +ss = AFD8B8D5D0F1AFB1ADE6E9BA85615A1ACAEBCD56C3541E8B50ED409071528791 + +count = 17 +seed = 8098AE7A92C10F707D405F7DEA02C2EFBEF44EFA132BA8AEFE81BD45E543ECEC74F10920AE48A40B0653D63532517F2A +pk = 433D0F9FBBC6418114F0E7A2672847294C915F175FAB00F2AF220BDAD477345C0BFA490E45E10E0B8BE6C7D494D32C68A934C81D1A6A880CD7BFBBCEF7265096C84C3E8EC25C4339DF659726C25DE4CA31D9799A34776EEB134EEF43A46CAE47AD332F28C60CE66C5A22852ED9FF2DEB5931FDC175FE84F4078E6DECE1CFF434BDE317398CB85EEA70BDFC69DEB0B60EB78697B16260595360068691C3320B3D6D5B191112646F211CEED149ADE146066ED904FDA739B1D28F1FDC384B8C6C0C390045893D82288F23FFB4E80DFBCA4807E461726B4DA0F026D577CC3CCE40296CF4E546E70A91B4D0124CF5AD6BC8FBE8B556F7955F16684B598A0A02C900E130C5E1E99C3366B93EB92A3D76372FF1393D941CBC63B9C97D5803032B141FE106FB3D1AD04EF6D8FE49CD059F1AE8FF1AACD32B0034E524D69089E57BE5F8BA9DA70AB7B1155440612865D789BAE822687EB7CAFB51B7C8D6159F95AA53485CD38B8E0F854F681DD1410B516AB159AC5124A070F25731370A71B4504D168B6F25C3F2D1E1526150D3CBE16EFCC41F19D4C4921EA305B388F474F9EB621571D1550F013BB50CD0E96280EA721002BD6543D0041F9EBB7DE4F943D667C238C04C6A853EB4BD925372F336DFF75ED18B89A6FF441FF86BA1817296AE263BC381C86621F2AE6FB8F43183531F26E25C3BAA69013856350514D097211E28E34CA27FD0B6C6D82E8AB824EA10FEE5E8B036728920466386DE8C9BDFF463E043834D8F2055C4B98692F8C1A101CA6962DED9D323FE105F +sk = B12F6FD965EA9C5B947DB80FC60C83D5E232DCA82E7263027C19BD62E5A6FF550F6AA3E88F7FA8A96067F8CDAECEEAC90C2D0B5E277E56E9C405EC9420C302520E0A9CAA76F59A0A6B1638B301A87103433D0F9FBBC6418114F0E7A2672847294C915F175FAB00F2AF220BDAD477345C0BFA490E45E10E0B8BE6C7D494D32C68A934C81D1A6A880CD7BFBBCEF7265096C84C3E8EC25C4339DF659726C25DE4CA31D9799A34776EEB134EEF43A46CAE47AD332F28C60CE66C5A22852ED9FF2DEB5931FDC175FE84F4078E6DECE1CFF434BDE317398CB85EEA70BDFC69DEB0B60EB78697B16260595360068691C3320B3D6D5B191112646F211CEED149ADE146066ED904FDA739B1D28F1FDC384B8C6C0C390045893D82288F23FFB4E80DFBCA4807E461726B4DA0F026D577CC3CCE40296CF4E546E70A91B4D0124CF5AD6BC8FBE8B556F7955F16684B598A0A02C900E130C5E1E99C3366B93EB92A3D76372FF1393D941CBC63B9C97D5803032B141FE106FB3D1AD04EF6D8FE49CD059F1AE8FF1AACD32B0034E524D69089E57BE5F8BA9DA70AB7B1155440612865D789BAE822687EB7CAFB51B7C8D6159F95AA53485CD38B8E0F854F681DD1410B516AB159AC5124A070F25731370A71B4504D168B6F25C3F2D1E1526150D3CBE16EFCC41F19D4C4921EA305B388F474F9EB621571D1550F013BB50CD0E96280EA721002BD6543D0041F9EBB7DE4F943D667C238C04C6A853EB4BD925372F336DFF75ED18B89A6FF441FF86BA1817296AE263BC381C86621F2AE6FB8F43183531F26E25C3BAA69013856350514D097211E28E34CA27FD0B6C6D82E8AB824EA10FEE5E8B036728920466386DE8C9BDFF463E043834D8F2055C4B98692F8C1A101CA6962DED9D323FE105F +ct = 9E3F95DAB5490C57F7097FD2831735FD273AAAD1B0E9886FABC47848637ED3169A8B494B71F2050223FCF2BB51F33CF3357F2AF0576C6943587A7DCAB8D584F699FA2A31462E2C572854C623482F98D5C72D5F92E368FEC396FEDB18ED4A49827B2F69387077F071B4FEB15E7197EE0DB55E8C1D1818A130AEC19423E8223113351D92AD62183E49A2438514E034DA08BDCF1FB6FCB9F96406F5A597A43C1D4D7020167870B46B506DE19CD28912068714F81D6D3B78EEF7D34437000A857A711142D29337E1EA7D6728E493CAAFEE43180C2F44ED365D18A95D0FC3F575F04D132B13EE5D7BEF9A2A8CA8BFFCD295999BF00F066BAE2AB762DF864DD9E8D1B9B78E12EDC449D7C0260487952F74C7C2FEF1437CA633C2276001D5BDD80FF33E9A1E7548237DFC8A00D325F5F5582E68BCA4AF5E13F5F0FBB0F6F5CB71D014666B94B21EC6D19A664CA34B8A57263185C7505A41BCA3E708CD94D36F54F43F4195845154179B3AF05E504BC05EC3290CD5625D27512EA13A5DB9298E502A77C9A3E04C4689E6944577B0A3A3F86A96B54238A589DD0486AB76A6A7B3BEB1FFD5CE76F21FA1B363310AC5F92BB7F913A9609A7162094C36FC8080B93AD56A827638BD1FB93AC893193C329F0861872A68DF099E14993A8425CFCC4EF07A7F671A895201AF2CF8D6C17ADF2E1265C8BAFF619A30263C04292D1DF58FED4C54C1AFE230C2A36BFC3DA2AC76B0BFF2618ED6C366F2513ED29AE908B0022B915F6F643696938E94CB191225D79A3FE34246FC0392AD4C43F9E98E176008AC27DF84AC4F13BED3B673C64D800E24576AED3D88C24C9246 +ss = EC2D4533BF7280BEC229663F6665053B5178A11DD78863CAD12FFC64ABD684B4 + +count = 18 +seed = D5F23808871544E9C1D6EACE2028362B48E225312F77663E9F78CAFEB512B908CD9E25875D61A16EC615F4B8FF826856 +pk = 6B46A039556FC94A95E2FF954AF485D2E39D8F979C10B805632E327793E74A19B04F26E1F90BBBFAFA4A9A9103E1FAF3D2852A739E61F57942B5A5E6F3ACFA6D1831128ADC3844092EF491578E0D7279EA2BF9DC3460E4E0472FEE795B6E05F4050349362AE1D990AB8B8C6BDA1051BC1E4B74CC16D208ADC2CB489402AFEA3D873F5E0CD1B3A44E919BFC6160CFAEA21B2E7A220FA784227756D5A39D12392976F09381E939639E6D9122398A8BAEBBAA13FD748CFD3FC4BDE8451F7225A038412B39D0F62962D75EBCE4FE916DD84342C0022FD5EBAC8F9816F8E354E8A60BF22F9ABC20ABA7B54E97A10C2965B6B2E4D99BA1D57D5AADB2CE89AE9722009ED180723D13F571853DBA243BC01D294E76AF2106B028B0D2CD4FBB0F01FE46BB831A68B6760961CC97BD9056A8AB34533EEA9B8A5A43C656BE39676AF28D0F4B45E5C8D0003861E56C0A2D03D28DD4BB1DE4B9AE1810AB85AB8F8B85EDDF3710101C3F0D4DE5FCFBD8AD92F58EC5A6A60C8A1A4E341058496E69E17C82303A1DF9ED7332F085C57AEA855424E3CAAA5A07A2ADB6468D0D95C44851635AA3B2856B9819EFA939EA9FA8CA52301EE8ED6F575B926906AF3B1687687DC36BCB1C1DBA8174191478D16345BF2E3BF907C6387FADC8F2405E541861D34DF6D8F8776B6099449B2D67BEA295EBDC44515756B514D626B66DFFFCD1A26C78698ADAB840264FAB769969139B2B911E6DB4662D7DDF81A64909FDA762A1333E724E76D41A5225D3DBB0EDC82917C4C8E2928C6314D751903B +sk = 9F52AF92CA165FDC38788F2B59BA02E01C8281FF7C1E60504688043A5FE814B04F3029E1BE4E1C0258C3A22FF5B50B2674CC094BA7018DA2A61569845C17D26F9580704792E5BA2904B75298DD8666036B46A039556FC94A95E2FF954AF485D2E39D8F979C10B805632E327793E74A19B04F26E1F90BBBFAFA4A9A9103E1FAF3D2852A739E61F57942B5A5E6F3ACFA6D1831128ADC3844092EF491578E0D7279EA2BF9DC3460E4E0472FEE795B6E05F4050349362AE1D990AB8B8C6BDA1051BC1E4B74CC16D208ADC2CB489402AFEA3D873F5E0CD1B3A44E919BFC6160CFAEA21B2E7A220FA784227756D5A39D12392976F09381E939639E6D9122398A8BAEBBAA13FD748CFD3FC4BDE8451F7225A038412B39D0F62962D75EBCE4FE916DD84342C0022FD5EBAC8F9816F8E354E8A60BF22F9ABC20ABA7B54E97A10C2965B6B2E4D99BA1D57D5AADB2CE89AE9722009ED180723D13F571853DBA243BC01D294E76AF2106B028B0D2CD4FBB0F01FE46BB831A68B6760961CC97BD9056A8AB34533EEA9B8A5A43C656BE39676AF28D0F4B45E5C8D0003861E56C0A2D03D28DD4BB1DE4B9AE1810AB85AB8F8B85EDDF3710101C3F0D4DE5FCFBD8AD92F58EC5A6A60C8A1A4E341058496E69E17C82303A1DF9ED7332F085C57AEA855424E3CAAA5A07A2ADB6468D0D95C44851635AA3B2856B9819EFA939EA9FA8CA52301EE8ED6F575B926906AF3B1687687DC36BCB1C1DBA8174191478D16345BF2E3BF907C6387FADC8F2405E541861D34DF6D8F8776B6099449B2D67BEA295EBDC44515756B514D626B66DFFFCD1A26C78698ADAB840264FAB769969139B2B911E6DB4662D7DDF81A64909FDA762A1333E724E76D41A5225D3DBB0EDC82917C4C8E2928C6314D751903B +ct = 07AC8DF2B03053C532F4B8FA9058F1CA872C616FEAC135C84AAD4C6D45DBE9FBA0FF786FFB261392EECD3DD92E87D9958B66A3E96C1241022B9625C3C5FC6103218A91522AC881AA98D4D5A3AF205C2526BAA2347637C28CDD0FF6BB9153C59AB7F869C32CE7D552B79DA3191F8B8C7CC52E24A498B0229E65766B95C6FFF6E34E37C48E0C5255224FDF8EF5706B4D68C4433A61EB30A25705E39F9F06F0804E1CD2160D416ED80EB7D755EFE7BE247CAAC4A51532D25F704A477A396380257B466534CA1A9715724F0005190851E2B7644E47E5887AD19718729AE086C36B09BAD826C8DAD8C88B94737091A63099D84826A45F24F94AE04BFDE791BD6C1988409C04A5C7891D4CC7363FB795C0C36907E251B986755CF30B56E0AF1CF921838F35E7F815DB244D2E0C05A458F03290D4154ACBE27AB3EBB0A28854CCC6371F1014FE2329703B9A264F19BC835949277CEDB453C4D31A048F3E5DD97417F6F3FBF3085E9171BCC9562248CA5B9A679F6005AF64F90946260DC25EE5A4C9D68FED7613B413E1F60BB70413A15E75B8EDD0730E1014FB886763CD58084BAC2DB9B97547C96CF6274B5961346F4BE578D631ED88C821034F07BCD781EFB8C2463C11D70F6B0379894731B46485FD093CCBA25E74A9834866533D16272BFA580A62F63D3E0DE1CC982C39270304C8E3393C41ECCFFE703A7896E81249470BD780747F3B3AFD6DECE57A1F5332EF1023F63941EB440C0045E226D0933607919B617414CB4A45781FACAA6631CCCB5B503D85BB00762CCAB158D1E9C214A463DF45732C0AEF3D195ADE2E33C6B0405E9C94F02E042397 +ss = 0D484236F0F718A7383605DD732B0CBD682C860F8899C84683ABAE97DF04BD2C + +count = 19 +seed = 822CB47BE2266E182F34546924D753A5E3369011047E6950B00BC392F8FEC19EA87C26D8021D377DF86DC76C24C5F827 +pk = 8447C5EDC4F5D326E1488C110D373A3594F20A7F56FACDA0BF9A5A7BD192811378B2B313C91A1E8E950D621EEB94FFB01444522FEAC10CDD48242595439F93A455A91716508CB110B67E022BED301FE4CF296E6F2139BC0D66F71CEAF442E0E90BB249DC6689DBB3171D802FD6A15CCFCC2753D998E3D680AE0C4BAA518C366451954F7B3C02ACF852AAA0949818DA2837F9340EA0D54F9245776C24DE782690FB59B3FBF7ABF634B38FBB137A70402F3DA6E52F51E87DC3E44B24038C175BE3AE895A41BDC4DA72D34DF12BBF2291FFFD3C65EB3EF7AA78E64B0274A52414E235BADA773F4418B7CDD710F175BA831C873BEA40318CB5C922D4E2A41E9B23A511E9AFEC2475054FB592EDEC94ECD6E1EE079439EF9D92212E36BD46C63BDD5BFC8CBCA5AD6EC4FF9101AE7A347CECE599A550A2805F973629B2334744E4D16A2A0446C0E4084C34E662F85A6FCC45BEE05BBF194D53A5764EB1D6BBCB1756006B2DEE2722991160773A6BB1DB069E374ED85BD9378E80570A147B0BB71822C84B00AFD932D9933806193EC07F2A0AF21EE403B4AEC02B7910A30B1B47CB5F717E7AC283BFBEB06771827F291AB2BBED20BE3C1962E3A1B398686008567F1A2A2F4419FB6D6EA73C46BA20075D8B39CEFFED51AD8B5F12D00E9035348B9A8B16A3CBF99F21C426F5D61E3FC66A7A466C2D0209D4ED458B1238BD8A34B7685AE5F100AF936BB71F6EA87D9CE51075B79132591A64B2AB068526D8213361B87D081C3AEB43FF75B7196E10090DD3153CF08CEB204B +sk = 851EA90FD3854CBF28FE39FB81F68E4B14345CF0D6EEE7EC4CE772513DF8410D1C0EC046899A777655233E4E1B5CA44E9AFBDC67964BFD5D5E3DBB45E60D03CFD77A9920C166C3AFEACBD5D9792799008447C5EDC4F5D326E1488C110D373A3594F20A7F56FACDA0BF9A5A7BD192811378B2B313C91A1E8E950D621EEB94FFB01444522FEAC10CDD48242595439F93A455A91716508CB110B67E022BED301FE4CF296E6F2139BC0D66F71CEAF442E0E90BB249DC6689DBB3171D802FD6A15CCFCC2753D998E3D680AE0C4BAA518C366451954F7B3C02ACF852AAA0949818DA2837F9340EA0D54F9245776C24DE782690FB59B3FBF7ABF634B38FBB137A70402F3DA6E52F51E87DC3E44B24038C175BE3AE895A41BDC4DA72D34DF12BBF2291FFFD3C65EB3EF7AA78E64B0274A52414E235BADA773F4418B7CDD710F175BA831C873BEA40318CB5C922D4E2A41E9B23A511E9AFEC2475054FB592EDEC94ECD6E1EE079439EF9D92212E36BD46C63BDD5BFC8CBCA5AD6EC4FF9101AE7A347CECE599A550A2805F973629B2334744E4D16A2A0446C0E4084C34E662F85A6FCC45BEE05BBF194D53A5764EB1D6BBCB1756006B2DEE2722991160773A6BB1DB069E374ED85BD9378E80570A147B0BB71822C84B00AFD932D9933806193EC07F2A0AF21EE403B4AEC02B7910A30B1B47CB5F717E7AC283BFBEB06771827F291AB2BBED20BE3C1962E3A1B398686008567F1A2A2F4419FB6D6EA73C46BA20075D8B39CEFFED51AD8B5F12D00E9035348B9A8B16A3CBF99F21C426F5D61E3FC66A7A466C2D0209D4ED458B1238BD8A34B7685AE5F100AF936BB71F6EA87D9CE51075B79132591A64B2AB068526D8213361B87D081C3AEB43FF75B7196E10090DD3153CF08CEB204B +ct = 2761653D18CE6C3006E8D60DE97E18277E1F30F21D77C92D3F52906C52184E21D71A1A97E77A6CA266490C630E969EC164826A053BAC0D2C742730A22D2A5EDA5BE71EF5E81D728847CFE82D9712D852AD9A9207A2B8ED97AAD9119757683DE7D143D51EBDED89C7A56A5C8FE62AD6406F973D30D341F87B65069FC1FCE15AB06984C6586A0A0F9FEF125416F81CDB4A243C61198F79AABD1D5DB476DC7EAA4D5EFC2D6172DD5510BBB1A9310B990AA0E6FA9A9E27A2F5DF06568D254E5F08FBC3D5094ADFE717B16AAE94DBA8307D280A8A520FF8D1B8868B62DCD08FEEC7C05BD278AE7C0BBAB1E74AECC63876BBDE053E316CF720C598DBC1DD74935C293F9B258BA915AD75F7E659638DE572B24F0B9E653ABE6B3B48015396F511518743FF8B07793132D6F8CCCF7D6D440B0B53EB36B183648829138A6EC0830761DDCBC6E18C85D351BA67769B46CAD703F0F74D6A99812BCE78C728F4BE4089496197A9A7EE4A3EE9E4452A4A85C7B3FA3D91F18CC6406687A865C6D183C76B6308E834C72833272DA8353725C50FD83C07D0CB49FF64376404612875FA886DFF3352BBB06B8F99B5E4E7B28374295AC35BCFC8DF428B3A04AEFB46DA8CA8A552EF2FF449FCFB62894E574AC53D1AF62CF1EC21DBF5ECA80C4259E856AC2A40D15CF6035DDC399435AF8055A0B4DCCACB589E957A7D86D1C385BAAF0BB9A1141CD895339CA97020038A413FF96226958224B40FD1EE32550D1D06FA10CB00D11F488029E137EAF5F46B636C534D1DE06EEFE54D8BFC43E07171446FA2873FF690F542291BFBE27C8DF2589A844FFE19F465B626CC74AC +ss = 1C22BEDBBC26C82AF8DCF84F69B8F6DB4877F12C4063098EAF9B3D8E574CDC86 + +count = 20 +seed = 81401DB81138D6874E91B7C11D59596E4ACE543F5A3471B6FB00999221765FEC3CA057ABE20F03B2D59003375FD71FE8 +pk = 2F216187F63E83351EB4E1171D41221B2554262CC70DCD9A75F1FD25357B7668E0FA7B37790B7EE2A2C4049CABD18028B2598FF3EBD8C12DFB8CE52A841C119ACA5DE4A1F784B99234E3A96E4CC4EA87F9DCBF79192A928BA73024CAF4174AA45ED852E40D30CD1DFC63223B7A7FFDDF7B4459D2495DF40AF064BEAA8348655011D0D8CA8E8923BDBF658014DFB0F5C38E498174E083BE5EBCE6B4F774F09534C19099B6028AF759314F951E0510B51841DC7B081BB6E5A516F6971B1F3E050816481701160E039DE6B44CBCDD4BE62E28BAAF96DE6224AEA62B8A6E71785B6F2F946CDE549F50BD98AC4FBF2B45D617134C699C79DD2E80B0766DB0C1BBFA22ABF8F639E83462E7CC1E039F9672EEE047C1055FA066A69CE11018B3B3587F26AED1B299A32B7736541F4974EEDBC4D6303A86D9DFFA492104E63E1EAAE7AC1E4077DD0202DED8F3B9FB3AFD0AC7D64572C39F280DE9110C3A625631CB0B52FE428F71D09C67D1BD0456E05BAE18594220E91534B0096A1C39C0AE52E4DB2B552D8C3EA91C0A3A9B285D9D5057FD4FCC6ABF44A12825F1F4C7EDE64E858F908CDF1184D12A7370112464963C20DF47EA1416392A81334B453F815F53C780C0B5D500C8740E3DDD8D447D24BB6BFCE261823EE211FC43E783B89D97D45A84223860E212E07E45623DD4F55723FB227A478BE998797B14B09BD5FA255E960BCBFB0111EA0E59E4E958BBC6AD67A2DAB873F648C05B3FF32FE2DE7F92AC2424CC8B17334F513F6E1598B94114DDB17DFE41F5D91F3B +sk = D304C9389CC973477F169788ABCB9D511F843219D246A9B587822F422A70C2386590A2E5C7ED86CF2C5C2A898662BC9A81418720BBB632EF9CF0B845ED052D73AFACA1DF98112891F60E2BC740C99E012F216187F63E83351EB4E1171D41221B2554262CC70DCD9A75F1FD25357B7668E0FA7B37790B7EE2A2C4049CABD18028B2598FF3EBD8C12DFB8CE52A841C119ACA5DE4A1F784B99234E3A96E4CC4EA87F9DCBF79192A928BA73024CAF4174AA45ED852E40D30CD1DFC63223B7A7FFDDF7B4459D2495DF40AF064BEAA8348655011D0D8CA8E8923BDBF658014DFB0F5C38E498174E083BE5EBCE6B4F774F09534C19099B6028AF759314F951E0510B51841DC7B081BB6E5A516F6971B1F3E050816481701160E039DE6B44CBCDD4BE62E28BAAF96DE6224AEA62B8A6E71785B6F2F946CDE549F50BD98AC4FBF2B45D617134C699C79DD2E80B0766DB0C1BBFA22ABF8F639E83462E7CC1E039F9672EEE047C1055FA066A69CE11018B3B3587F26AED1B299A32B7736541F4974EEDBC4D6303A86D9DFFA492104E63E1EAAE7AC1E4077DD0202DED8F3B9FB3AFD0AC7D64572C39F280DE9110C3A625631CB0B52FE428F71D09C67D1BD0456E05BAE18594220E91534B0096A1C39C0AE52E4DB2B552D8C3EA91C0A3A9B285D9D5057FD4FCC6ABF44A12825F1F4C7EDE64E858F908CDF1184D12A7370112464963C20DF47EA1416392A81334B453F815F53C780C0B5D500C8740E3DDD8D447D24BB6BFCE261823EE211FC43E783B89D97D45A84223860E212E07E45623DD4F55723FB227A478BE998797B14B09BD5FA255E960BCBFB0111EA0E59E4E958BBC6AD67A2DAB873F648C05B3FF32FE2DE7F92AC2424CC8B17334F513F6E1598B94114DDB17DFE41F5D91F3B +ct = 24E6B35B6467F07DBA70F013B61F235400EDCB76FD24C4889FFCA2EF2B048611A0326F1E11777599E27645703024D311CD1CC3E90AFD1D8DE333B321CF2DAFF3862BBB94AE2C05579B38D105EED9CD38DEB4B1CD441ADC29AC8E25268E542C3CBFCAE2F79CECA19AE543D81A2955507E1001CDE8B2AAD49AFBC177333F29FC9FA2CFFA4F277F9DEF7A8483F75EFFC09013A79F81DE87AF538F63DFEF8987E147CA5DD6865354C2F23D920AD303CF315F2E881405590996825E08C968B76C2DFA36089C3F3008C3090E7D4B6E518E3D9731AE99714497D29818A442BB56EE7B6EF0774C26C6B06AA92C868683F046237D9FDFF5A8A1FFD08477A91A82360A86D06AE537241B4526779D78B7563D20FC9F16539A2894EFC2F5D621038C71E7DE3EF8F9BECC7DF0204C93ADC4606A3878D7BDEE8A15C0D1058CC5ED391F146F41F87BD6126ECD6577323883C948DCE3083A110411DA7121E53507EA1103071AE9B5DD0014AE48E8A0CC714B9740E43BCA8BB13B00229072912F87E88BF44CD2343FE8E787772BFCDB8D81E25E423828981BC51C80A8975B7D993D11FB4126D96C312ED75FE77FFF521599E839CDC5B6858FF66A5510C027563169D3BD9C8BFB66E13ADA61DA5983E4F6CE00038F07B189635FE5F1EACD43C0FB18907DE6621565040297672502829FAD6AED578AF8A8B948343229DC4E916BD9668F68574AACBBD56BFB85A6948042D68A88F9FEDA91370A2497CBEBB8CEC04F808E706596135BFB88C6C5C041C62C03C6676789FF734D43C1897B277F50397955C06610A67308B9CD13B138AF4C400EF0E4B4C892010B51E3A842D1 +ss = 901E8EED2324D6571E0940041B4243A8771F0C72208EFAB0B7DA51E57387C5AE + +count = 21 +seed = 30B5DE5B73681EC08AAA03F6F2D2169525D25F4042A5E3695A20A52CA54927B85F8BB948FC21DF7DEFC3910B28674994 +pk = B70C1B535C4947E61B10DF795170263CFA724A41415E32E674721843421682E6E307891BB03C5BCBCCDE460EABFDF5E56E3F7CBF21807982BA4CC1685482CF36DB9D85F709831D8D186293F2380677E2B5825D59ED21CCF2BCC16A8576357FA519A9A2B51C0F98CA80E7506EA33C439C2E3D0C91084D04F0171528C85B500857DD40DFF4BBF891E1E1CFC8A25E6CD46F9BC9AA2B9D087A1013D45065CDE85DAB2CD5655F3A2C94E4BE790193AA51CCC72FBF0DD7D60E3B2F7578F314A5D5B719F76BFB2E5FC2AA0C68D78294B90652A478F9F0BEDCC2A04488AECB671823BA4FAE5AD39E61A49EBFF194B84A12C87FCDD2A653F0BB1925705F4AED332A32C723F50B523BBF1D945218B32E2BC6D61350AA67261F9401683FE2612918872021E819D284BC319E449187405793EBE8CF88A96CF00E1E02A9B5C33C2AB0BF0AA97FBF826296E3DBFCD34F4BF803257FFA274FFD99C97001E0AA19251389C050A1AE922ADCDB6B472D854B5E05FB53BC520A8B0EDB1C4599C245FCC08400891F1A713A4FD545FD594A90E7F2978405C743C2C975A757DBC144911A9F5F530E2B8E0FA014282C0B4E83BC8C77C4D3A768856CA6D1F9C8F4361A7024902EF414B39979D81434765894E56C9D36810812B9DC8E26C3000B86150E3E6F0B0586DD21734A1F0F15A7B952296579F58445A95E1309C4F5386DA4B0C6141ABC57495B3DE0F083147F265C8050302E57AD4447D12388A5B0766034CBB1B4B9DD5F8A32C303DBF8DBE5E540C7D79760D309B27EA178C33403364E +sk = 89A6E3BE304A3518FB82B18CA730F0B359CD6BA90664A493FB4F8EDAF965B9C3B6591121E25D64010C25A18676033E1D7278AC5F2D0B43A31F3A4156AE7104656018DC349AC67563849A29C50DB66103B70C1B535C4947E61B10DF795170263CFA724A41415E32E674721843421682E6E307891BB03C5BCBCCDE460EABFDF5E56E3F7CBF21807982BA4CC1685482CF36DB9D85F709831D8D186293F2380677E2B5825D59ED21CCF2BCC16A8576357FA519A9A2B51C0F98CA80E7506EA33C439C2E3D0C91084D04F0171528C85B500857DD40DFF4BBF891E1E1CFC8A25E6CD46F9BC9AA2B9D087A1013D45065CDE85DAB2CD5655F3A2C94E4BE790193AA51CCC72FBF0DD7D60E3B2F7578F314A5D5B719F76BFB2E5FC2AA0C68D78294B90652A478F9F0BEDCC2A04488AECB671823BA4FAE5AD39E61A49EBFF194B84A12C87FCDD2A653F0BB1925705F4AED332A32C723F50B523BBF1D945218B32E2BC6D61350AA67261F9401683FE2612918872021E819D284BC319E449187405793EBE8CF88A96CF00E1E02A9B5C33C2AB0BF0AA97FBF826296E3DBFCD34F4BF803257FFA274FFD99C97001E0AA19251389C050A1AE922ADCDB6B472D854B5E05FB53BC520A8B0EDB1C4599C245FCC08400891F1A713A4FD545FD594A90E7F2978405C743C2C975A757DBC144911A9F5F530E2B8E0FA014282C0B4E83BC8C77C4D3A768856CA6D1F9C8F4361A7024902EF414B39979D81434765894E56C9D36810812B9DC8E26C3000B86150E3E6F0B0586DD21734A1F0F15A7B952296579F58445A95E1309C4F5386DA4B0C6141ABC57495B3DE0F083147F265C8050302E57AD4447D12388A5B0766034CBB1B4B9DD5F8A32C303DBF8DBE5E540C7D79760D309B27EA178C33403364E +ct = D496757BDA1B8F2DE60F21C40B267BC4E0EC7A03111EC445B0BB45BAD2D8F9851DA4A833267038998C34CCA57480466A7CF6D67F9A2744550FC8DA3E9C04656C9F7E52ACA8E884EFAB51E7E3A3A5444A99AB3531BAA7C5A89FF2C701E145BC1F957F3FF99DF06A4F24E63E1A9E0A2A6169CEDFE2E94E51E0316E1813A11D1AE020BDB660B4B2D747096EAD1833893BB62BDB09463B72F46BE42552A9336533E2A5A7E91AC9EF04B69AA5E799E1C4C634EEF62C52265DD75E7450C26C56F9BA0F43B7BF46CFD06A138DC67480B11400F6D4632B61D3E0C6335D8F5C6B3C584526802D590EC013816FE9B4DFDC6157044E9D87410E0DDC8F88355A9161C10A5ACF64F3D6783FB94E1C596138EC6D4991F8D8BA1E1DD31CF83AA43E4E5940563CBDB72CA88EAC813780887936C8CA483FF95D5B6F193C9C8144052838BD4656B0FF01CE23BBE87E30EC3A5079F7076E4035FD84B183D8AB52C295FD9BA161950F3BAE15313A7602088E5392250B8FCDC2034BED93F2E4FC7266E26AAE2425F62C3F16D22A0A97055EC3C0171753F6F60F225E09D1CF6281331B495FE056E64D607A69DC69D946581C38640706C5F77AD7DA0ED54F1476E98CA00945C4445583427E44736470E3E4BEE42BA09E58A1D159ADF176B8878B6A00B04D96085474CA4C14FDD3A9138E11A89CA6D37F925FDC309696D8874367682CFE7446BF74380785C45FDEF7DD49035710CA079193DA8D5B0575B682A7B98A97C031DC2F5BB4FAF53E15EC90875F11E55D27DAB32A690FBC681751D02693ABFDAE43F75CA3ECB9717447C0724B0146B3602E2C07CA9264DE1388BC6893 +ss = 54173A3AF286B4F253B6DD8F013F0C025A03C2086E236594D98B0F4FDFF1F178 + +count = 22 +seed = E335DF8FC0D890588C3E305AC92C7160FF199E07C85760A828933750E3FED8C83B0DBE802234481ECF890A32D7A2884F +pk = 663260B7BE72AD45FA145B2F800E335387868F11802DEB2BCF452F551E7221C1981EEA05F09EA89356001E8FDF27A982E37267D8314E3758364DBEE963AC04B2860C79A9B5BEAFEF5AB4D03109EACD60A24189F94D7AA09EA544FDCD4069E3797001CA8BABB6EB03D08A7872445803411A818A83A3B7A144AC90462C0C27D88D69129CDCC291E48FEA29AC4F6B15C389DE7F183830DD077F082E2F1DB5C9B1904C42DC112146E2A73F7FF97D524A67B5936445B07625D37914353840768BBBFDFBEC0C7A1B657BD397AB1D954C0BE0D5CF8FC512CA79FC68A5CADFD52DDCBC463535750B2D83567E39D36CFD3F113B3D989D7B0A10162A78479CBBBE53F97E16CEAD383B08DA76FDD1F323FE44C63E48AD9D654D45C556E5E4325AEECB8C2769E40CE22AC0A4E612DBA0F349BF1CB00075228133EB5C5AD49295FEEE084BFF26FA55BEB8D35721E9EDA48BC5CADC9E69D1EBB6B1180152ECAFDB0804F234601E7FCCF8125C44608133277C2FF89257622EAB9183D891DB134DEEFFEFEEEE1632742D74CA0674609960C6429BBA4A252F0D42A7C49F8E737AB70F7ED310E38218ABD3D5F40228FE2B9BF97257601AD4F9E9A323CE1ED07F66A32B9013D4504B910E5D4729FAA8727A12C07FDB831864A15FF45F72D33D58C6CAF0CA6C45E6889FA1F52A5051CC2480674CC9B94231AB874D48D0576011F4AB8EBFC81AE15347F23CCDF13B4F9712C90C7F7F73EA72FAA19369C927F89796460BC479AF52B725E7D01C22E5D428F0C2B062874BA1650262D0090E48 +sk = D569B935CE015C85F792F8F7FB0D83C4F53B492959361DD4F75FB764D656450176EAE84D11C4528382828F7A689A0D5CFF87B8CA0BBA97FEACB39B935A8788CBD0C65DDFB25BCBA0941A944F63BDDB00663260B7BE72AD45FA145B2F800E335387868F11802DEB2BCF452F551E7221C1981EEA05F09EA89356001E8FDF27A982E37267D8314E3758364DBEE963AC04B2860C79A9B5BEAFEF5AB4D03109EACD60A24189F94D7AA09EA544FDCD4069E3797001CA8BABB6EB03D08A7872445803411A818A83A3B7A144AC90462C0C27D88D69129CDCC291E48FEA29AC4F6B15C389DE7F183830DD077F082E2F1DB5C9B1904C42DC112146E2A73F7FF97D524A67B5936445B07625D37914353840768BBBFDFBEC0C7A1B657BD397AB1D954C0BE0D5CF8FC512CA79FC68A5CADFD52DDCBC463535750B2D83567E39D36CFD3F113B3D989D7B0A10162A78479CBBBE53F97E16CEAD383B08DA76FDD1F323FE44C63E48AD9D654D45C556E5E4325AEECB8C2769E40CE22AC0A4E612DBA0F349BF1CB00075228133EB5C5AD49295FEEE084BFF26FA55BEB8D35721E9EDA48BC5CADC9E69D1EBB6B1180152ECAFDB0804F234601E7FCCF8125C44608133277C2FF89257622EAB9183D891DB134DEEFFEFEEEE1632742D74CA0674609960C6429BBA4A252F0D42A7C49F8E737AB70F7ED310E38218ABD3D5F40228FE2B9BF97257601AD4F9E9A323CE1ED07F66A32B9013D4504B910E5D4729FAA8727A12C07FDB831864A15FF45F72D33D58C6CAF0CA6C45E6889FA1F52A5051CC2480674CC9B94231AB874D48D0576011F4AB8EBFC81AE15347F23CCDF13B4F9712C90C7F7F73EA72FAA19369C927F89796460BC479AF52B725E7D01C22E5D428F0C2B062874BA1650262D0090E48 +ct = 0EAFD981806416DDB6A763494C23818A09161A1A574198C41AB29214BD8F05C326C36CE5C31349642455B89BD9746AD64F26897E0F37E1642F96AADDEFE2233E4E480C4EA298B97AA1CDE5505C2E7E03C85477C339CF48D62AFE7998FD0842CEAC3F41FE954B18865157BB0B8150AAD2352AD4B83010F091EEDAF2F8B51CE36DDEBF3B381675E163CD28D5D46FBC53B1F3DF4CE170175CD3EFB7B4D8E58A275E042AB27D6572CDB0D8468779ADDA864BEE789C4F5618E398D70EE8416C6A0CF7D22C534D5E616BC0345C66C12A3AB7A6369FC2F060BC049772751F3051A6056FAF117DA3FDF3FFEFE5542AEAE310524EC825FFE5347D05EA4B1F33C37FE21CE05A46C2CE690E4A76D615778B79E7B0AF564D8096875245C2F90F74B9B7588B6780FFF5F6CEA84CF9B1DD9D8FBF5DD469543ABF8CDC5B4E862074CC5C90E0686A319D2E6AC76F58E540ADFF3CC9A316F7A904D70134F9F0C0385BACEB55A0A09540138130B0271931899B8608B85B1ED7B2C7D083B546432FC1FBCEC28076D566284D4F94896BF5B2A3C44F1D878CFE6771DCE6BC3DCE33D3FAD4ABE55ED9A353C4E5D14F077F3CFAEBF5FC2C64FD70B1A6E4FDB69377FEBD8B36A75949181BB3DCF738DFC3EAADF583BA81174896AF3183CDAF1E714DF1D5691DD84D0CB8E22B865BF336E67C58C4AD129CBBBCDBAC42EC86C23BDE1E1AE2A6558B9A213B88EC5F97AAAEB978768F99037A700C9A5D8DA5173518B5F951D7B954A344CA17DE58F1A919D251B45FA41AC5201917E553F2E802223CB55FFCB662D4586E9D2A37E31A629665857C09ED53174D0C864BD2B4AE3B12C4 +ss = A9562321DF5970375856AAF0BC0416202AA3D570E4495ABD5061483519091D6D + +count = 23 +seed = FBEA1BC2C379F4F8FDCB0DE260D31CDB064C9EA9B1D6DFBE91B3692ADD1D34DEC9C9FFAE7BF5E72ED2743BA3F9F2E43D +pk = B44C351990310EE5ECEDBAC6D1A6A5DC01DF5A1C9C7ADF9EFF5E8515760414D33AF07925C86F9026B2E1332BCC3D4C4FB2B493ABED5AF35BB683FA97D6F86DE2AEAB800CF2F4DBBFBE029DB6BB56C1104A1F8BD1F06FEDECFFA05C749E5B01146EBD335A6C16B5E9420FA621233DF6F27AEC7FE2CE418F8882EEAAC70263A75EC579CE31C4579DEF56E03C94C0887DCF9429DB6B866C3058B47DEB34C62FFC28D32C189F31AA620AE82FFB1038D5B8E499DA89EFB97C233AB0721F5E04D4E6EB030FD8501C63C93F2AEB1DFBB9B7D06FAD8436564DB022BED3D9C1E1EDC62E0ED1AA3A84582B8219CC77217C592A3DF1C031CA0F64731F9B96B62DECE8FB659228A52D6375E2EDEEBD884E45410273A2DBBCE6B60F543B57D663EE65787EF04EFCF182DBD4AEED5F82A99D7DFF7B22C1D3C8D4BCD54B75107ADFEB6FF4DDB1E1C38907836E1F65A5F46D40F161B78BAB03BAE4B557C42BBF3B4462FEAE3DBFFE4122A4B44F98DA92EF9ECA2474343D0DD5F1E241EFFB3049E7C2C812335ECC83613BDC558380E1BA70C56167C2ACEAA7474716FF0507BBE50CF9B5093B146FFD0AE6F8EF2107AA2A1F5E575633C156ED90B543235CF739174E2695246EB6B1BC21E8345ECD621134188EA4830B020CD02900804D152619A64248490039EF34668E37ED14C4978B751BAD878AE073C038B290B8844CA5DAD395A4CC07218CCC6A8879BA96C55D5C42A77C4213B019294B5DF43E70E58F0AD41BFC4F1A34E3B53DED4905B98ADEE24B71C02FC06828B283D981A217 +sk = 5CBB141C2763425C274F7404FE530D9116E08C33F9F200A20B011CF563A28990FC9EBBE336DC464489861DB8253606971BD0A9008A433ED17752D0402378155291D745C4BB3A03D40D4A65330CFDAB00B44C351990310EE5ECEDBAC6D1A6A5DC01DF5A1C9C7ADF9EFF5E8515760414D33AF07925C86F9026B2E1332BCC3D4C4FB2B493ABED5AF35BB683FA97D6F86DE2AEAB800CF2F4DBBFBE029DB6BB56C1104A1F8BD1F06FEDECFFA05C749E5B01146EBD335A6C16B5E9420FA621233DF6F27AEC7FE2CE418F8882EEAAC70263A75EC579CE31C4579DEF56E03C94C0887DCF9429DB6B866C3058B47DEB34C62FFC28D32C189F31AA620AE82FFB1038D5B8E499DA89EFB97C233AB0721F5E04D4E6EB030FD8501C63C93F2AEB1DFBB9B7D06FAD8436564DB022BED3D9C1E1EDC62E0ED1AA3A84582B8219CC77217C592A3DF1C031CA0F64731F9B96B62DECE8FB659228A52D6375E2EDEEBD884E45410273A2DBBCE6B60F543B57D663EE65787EF04EFCF182DBD4AEED5F82A99D7DFF7B22C1D3C8D4BCD54B75107ADFEB6FF4DDB1E1C38907836E1F65A5F46D40F161B78BAB03BAE4B557C42BBF3B4462FEAE3DBFFE4122A4B44F98DA92EF9ECA2474343D0DD5F1E241EFFB3049E7C2C812335ECC83613BDC558380E1BA70C56167C2ACEAA7474716FF0507BBE50CF9B5093B146FFD0AE6F8EF2107AA2A1F5E575633C156ED90B543235CF739174E2695246EB6B1BC21E8345ECD621134188EA4830B020CD02900804D152619A64248490039EF34668E37ED14C4978B751BAD878AE073C038B290B8844CA5DAD395A4CC07218CCC6A8879BA96C55D5C42A77C4213B019294B5DF43E70E58F0AD41BFC4F1A34E3B53DED4905B98ADEE24B71C02FC06828B283D981A217 +ct = 5D3F6095089C663CD768FD9E87B01EE43D5EF58CF01B40F89B67C48C7CB00E06B478F89E21516AFD991D4A2432DC1AA3671AC02C7822096074FF11F7EC136DDF0836BA0FEC5DAF45164E6935ECF4DC2DEB34BF9440730F895D14D269D41AF3F6E11BAE275B269C91BA0A19729BA818D0A56F62BDC864831714C74896512C84B2ED1604AF659C4F4A28B794CF3AA87514F3C90DE6638B77EEAA546033D07E51D40E4110B51B1D937BE98F691FF67BF629EBFD3AB5C16A73DFBD0E900905F380074024EA645DC26248F6134783C07FEA1E255343E2137FB1882F46A5151B1E2D92BDB2D376087AF69BD7B81E3961D2EC7383A2FCE01AC280B00BBD8C4B90A5C5810BA455E7B5413320E23AD2507F7E8582056DAC625B88E19B933C1028E9F56C36C2ACBE741FEE7F8CD2B93AA72020127BCC15F56EB8B56234070837F2312C942EA0A51E11057E91B196EBF060DFE54E8044EC123A1E6F41147A136CAE6F99C8A305D9E81301AF4430EF1B31788034DFFC927A36B307C8A3021D8FB7DF182D9D94EF2908DB4CFAD8BA313C165631BC6C698D0CF724554A47CDCD11BF51ABE8C64051B5D3266A7582C485051237AD06EDD725FF0EF7771C17A77844CA0E4B0E2767254DE01DC974BDAB4B6DFDB15D16ED30FA7A3E418C1BBB6DED280BEE7FDADE46093F90FCA261F97FB14BC73B396B8E48A15EA22A021434B11A093B94808278F1B726617198B8B78846D9AA376ADD45509E25EC3D05AA515BAE8692B8AA9BE9EFAC3320E1EF102FE276C73F4BAAEBC51672B4B7127295E961F7321685715FB8621D6E5C39FF8DA37570CAEADD4F39403ACDA09873 +ss = F48295BD40FB0E919907CD0BA11405B9ACC83E48E5151754E8960B8E67B62350 + +count = 24 +seed = 7E87FB886BC3C7C9FC12569F465D2ECD12532E76CC27C65644C8D3DD603B0CB2D036C5974E675058F271D5C82AD7A813 +pk = 5A4EEC7C08E6C55D7F3A7B2D50164091FE12B13AEB0850887D72AA84EC239122BE28EAA6C17C7DE0F48E9F9E36E63BB3ED7A3FDFD2906F6578FBD2B622B6B5F1DC8F717C2B32DDDDC553472E5DF71051F31512F82ED947475B2AE2CF0967BBB2E3239B24CA4D3905753182E2599332600881D9F1A8D03C0878F90D8B44F8C7C06986B666B36CE0DB1900F756711637381B00275EC70163A78E3197BDE22C24B01936D49FBCC1D2505CC77C0C6B72F2808EC451F062C8E8D15AF8476E7BC4631B481064753DCF5838089C172F3BE1EAE6CDCBDBABC7C0AF95524C0451A1E5062A0557C124C06421669D54DA24425804026E7690293EC4DCBA416AB7D89BA50843BB0FDA6133A90C7018C5FB105D6BF082B4ABAE28C61E97D4E10CC139374016574FC0576F7C8E85A4643C20D7BE91ED6AE2136472808307AD75B588074A7F065ADEFCD1CF70C3D53F07A6E478BF92A513D4383B8EF0B43B4A814C44887ADB7E09C4B895B4FFE54B3053A5A29535F42F37F33B77DCFFDE292E57F6B89BA9B1845DD9CF88A96AE34DE09996A5C28E93D84A4C74C6380280AF7F35B2F7ADCD78A1A1DB254C1DF63BC934E681D8590B76D6855A51DE92F1C11BE712ADB9C6BE1C6879639D1FC78CA27D794BF3B05D212769488B7CEE6F54580875EA8DA413B8B41F9EBD4D901AD46A0DDB57FA1ADED4A8EA46D454284D995506D5B752F00F427835B27132D22D4FF93CCE02BC990BA383CF4E47FE6DFEB6412C61594000A0A4D40E073EA4E23419DEA3759ACC82429D3456AD65C5BA24 +sk = 293ABB6D1C207927945417CF84883EF010823E11B487ED55239E466E83696D0CFF8563038AAD865A817CAB9CE98846BA75BE9363718ECF5FEA538AEA90B2A558FF5DCFF670AB5482D6734C622BDB0E035A4EEC7C08E6C55D7F3A7B2D50164091FE12B13AEB0850887D72AA84EC239122BE28EAA6C17C7DE0F48E9F9E36E63BB3ED7A3FDFD2906F6578FBD2B622B6B5F1DC8F717C2B32DDDDC553472E5DF71051F31512F82ED947475B2AE2CF0967BBB2E3239B24CA4D3905753182E2599332600881D9F1A8D03C0878F90D8B44F8C7C06986B666B36CE0DB1900F756711637381B00275EC70163A78E3197BDE22C24B01936D49FBCC1D2505CC77C0C6B72F2808EC451F062C8E8D15AF8476E7BC4631B481064753DCF5838089C172F3BE1EAE6CDCBDBABC7C0AF95524C0451A1E5062A0557C124C06421669D54DA24425804026E7690293EC4DCBA416AB7D89BA50843BB0FDA6133A90C7018C5FB105D6BF082B4ABAE28C61E97D4E10CC139374016574FC0576F7C8E85A4643C20D7BE91ED6AE2136472808307AD75B588074A7F065ADEFCD1CF70C3D53F07A6E478BF92A513D4383B8EF0B43B4A814C44887ADB7E09C4B895B4FFE54B3053A5A29535F42F37F33B77DCFFDE292E57F6B89BA9B1845DD9CF88A96AE34DE09996A5C28E93D84A4C74C6380280AF7F35B2F7ADCD78A1A1DB254C1DF63BC934E681D8590B76D6855A51DE92F1C11BE712ADB9C6BE1C6879639D1FC78CA27D794BF3B05D212769488B7CEE6F54580875EA8DA413B8B41F9EBD4D901AD46A0DDB57FA1ADED4A8EA46D454284D995506D5B752F00F427835B27132D22D4FF93CCE02BC990BA383CF4E47FE6DFEB6412C61594000A0A4D40E073EA4E23419DEA3759ACC82429D3456AD65C5BA24 +ct = 4B1CD69E09BAD8C50E39EC393ECA8012E195B9EB5E4C39A0DB4887D5029F12D2F6EE334D5C39713346578F8F08FA0CE8F9343A94AD8970878F1C0F4625DA8DDA9C96D04397C7FB1F27C933806211CD4EA9E3EC1F30D53295A1B8789CDC116962EA7E72221F89AEF3BEC0B3D243DFE4E0144B0930AF35320D749E480BB50B40BD0AEF888F795B90D0EEEC3855989812CF608D5D4A56DB16F282FB11C9DA44EB281F84B622C4D75B9C490BBD14DB5CFB93078B1A23F6CDD12D2FB70D006D0B94B30568459656ACD6998BD9179246FD2FE544BDC19C72375E02531BFCF78498ACDF665F3BF67F698C004A749BB645B645932D85E9805694CD4A22B4FAC2541FA653508BA12DC6FE2B380671AAAAD355496E5B864ADB2E6FE465BC01E4D503E31FF9B32B20ACF1710D392171A1EA47B549DA2EE6A0555EC39A62941B5AEEA21457F3FE78C8E9DA722CBE7259796C403E2E73D7DBD721316B2A6C2825BF5126ABB588D23EB3A27FD72BD4C067F78EEB9D8EC5DC1F6A3B617AFC534E3533C82B11FE5A05D4419ABDD6D2C997D48764DED9B01A78B8D70D2C8E6D611304FB4AE4D8E2CC280380E818B26CDC804927FF6326EF397C8BD47CE8D0ABCEE650990BA4B9835406244CBBBB52FFDE0890111C34B5AF7A7DAA0E724E3B276B47DEC046BDBF5A4C75C3E0A09A80E46A9F03551F92898608FF46A678D183D428B6FA546C56A3F7919E0D84533BBCFA5F72522558DB12A3CE322D0BAF6FB44B6910D19A517B7C9E2D1813F00DF8ADAC95162CB44F6F5B48AF0A954521A6705B505188409AA76624DD6226CEDF3687AB35CDD91A26F6336C38498B09AF +ss = 28F8E24C2F07FF65E730AD254594D812BE3E5F2F1C70CF77542B084A8FBF9535 + +count = 25 +seed = AD1424E804F306C7FF513DA4C1E8D445AFCA7BC942FAC5C0B335733AAF70693712ECBDE26EA726EE0F9FD9D52A83B1A4 +pk = C0CCA24B8A8C6256DC1BC41FC92DBF1B188B1975D39702A5999F3738EB97EAABFDA9A4FFC18A9656405E4232E2E226A133A9129E0D8010D4DE0B373C6286528F305571109D898DC9E03C978DC95466076754A80DE2967B708369FA3907243B32C79127E41E20DDA5380DBD14BF26813D5B3E80D1009B304E7BD901E0AA3E17E09F8F2E21A7095F9BC07CAAC305CDF89DCCBC50A55A30952AED77DD1175648318D180D4B623777A0E7F5AF486BD315F728CEC92C50AD030BC0496264D2E9BFFC2026413A3C120EF43C70C432E3EB7D0A567E766D21AA6D325F431E060CD419110EEBAA157AF0479B5C9DF1B3EDBF773C24E383019B8FA76A2EA018CAF390C21C379DDB058440146F989A50933CFEBBF5ED487313719F7D5F0286D34D55C953A08D957482253E4E44ABD3B8748F28F2409C6DBD032A28A17C3E5A81998387684804EA64625B6D514E7C87109A4BAA29B2DFD456170956D16B01C25A5F63658C57ABA6C9950C89DDF7F22CF922E14FDFAF5E0D7F6ED4D88E515492A82E85CFE881B95A22F5C8F6DB5B0E9464279DACD0C1B1F0E67AD17752675E5D68F398CD1FACE3C4FEFBE1AC6DD1AAADAF6F006BC0FBD00E23893BAF397C3E66DA18A9D57F7DCB25F929326D2D23F5277F2A8E71FE3648C739CB0A162AAD21810E7E86230D166941CDC73AA6804F15DD2268BE9C623455BEE7B06623C9917E68C4F0E1504C8379AEE8339617752DFFF3542E724AC08728796A2728B7DA41A1DFE30D1C4BFE5D4984FB008641F299ABCAEC46E9418181A1FE6146C +sk = 74D87C7556F2671F2D666854A4D6E073E69F35421E6E1A428CCCEA49C37F972CE1FB7456AC0AA1B97068F452CBA64EBDC138BCF5D36B0A0FADA2A3B374141EB99850E03CA7F436DEDA9D54E13BBA0203C0CCA24B8A8C6256DC1BC41FC92DBF1B188B1975D39702A5999F3738EB97EAABFDA9A4FFC18A9656405E4232E2E226A133A9129E0D8010D4DE0B373C6286528F305571109D898DC9E03C978DC95466076754A80DE2967B708369FA3907243B32C79127E41E20DDA5380DBD14BF26813D5B3E80D1009B304E7BD901E0AA3E17E09F8F2E21A7095F9BC07CAAC305CDF89DCCBC50A55A30952AED77DD1175648318D180D4B623777A0E7F5AF486BD315F728CEC92C50AD030BC0496264D2E9BFFC2026413A3C120EF43C70C432E3EB7D0A567E766D21AA6D325F431E060CD419110EEBAA157AF0479B5C9DF1B3EDBF773C24E383019B8FA76A2EA018CAF390C21C379DDB058440146F989A50933CFEBBF5ED487313719F7D5F0286D34D55C953A08D957482253E4E44ABD3B8748F28F2409C6DBD032A28A17C3E5A81998387684804EA64625B6D514E7C87109A4BAA29B2DFD456170956D16B01C25A5F63658C57ABA6C9950C89DDF7F22CF922E14FDFAF5E0D7F6ED4D88E515492A82E85CFE881B95A22F5C8F6DB5B0E9464279DACD0C1B1F0E67AD17752675E5D68F398CD1FACE3C4FEFBE1AC6DD1AAADAF6F006BC0FBD00E23893BAF397C3E66DA18A9D57F7DCB25F929326D2D23F5277F2A8E71FE3648C739CB0A162AAD21810E7E86230D166941CDC73AA6804F15DD2268BE9C623455BEE7B06623C9917E68C4F0E1504C8379AEE8339617752DFFF3542E724AC08728796A2728B7DA41A1DFE30D1C4BFE5D4984FB008641F299ABCAEC46E9418181A1FE6146C +ct = C5DF201D60832116DC496AC6A7A191ADF890387F9F5FFA09E7A24F25B2EEA7AFCB4C9B44DEBE99394D5C05A6CF2A055806715069510F50D27CDFE5C047C4B923CCA68D83D5FD907CD2B13052E3310BB732782E0BA431957A29DBFD61F76A7CABE3D1BE342D2546B0618A52602E8923B6786AA2273B8CD6909B66E47163D63B9E2E1DD7B4B870CAC52B3EF9C311A17314F45CA70D40A29E3F8F2741EAAE462B130F1341B98D661B8AE24D53BC34401475F4763E08349E349298FAC22368961A8C2A3110C48B3440A3875196048B8E1E23F3DD3AF05A804141A9BBA449EB405BBF743433B059BF87132DB01B117497A2EACDA0FA1423422938292CD6F2F495CA791B27C238AB1466CBC6B652699BF37717B6100DA210CCD196305C81B044880DCFAA48ED2A0A5103EC384B6194C1A018E3DF8293C29B4091455455838545E852F3A11000CFEB2B8184804F075FE5BA605C69A6DCBC681F3FC2221C29E034C6125D6AD5A2C80F0554AA6D10626B37ABDF904765A31DAF59CF100C2052F4D389F2688A9499362A8E0A514823CC924ABFF917B1595E6419121BA4364BD07EF478127411ADD1B04803F3B055F19DD6783C9E9BD3FC369286658087585228BE68A8FCFBDBDDBFE65E4A9F3D95811AB58401243585325C3F132DF14A5B4816FC31E927B9D975357C9F927C7B117B5149B516A750105167FE97A2DA620C9F97A92033C39DA82A7745973E38171BA41EB83B32C787695A9EF889EC5FD41359A6BC0FFB942D16941170DE5EF37033FCC4D1F8BDD95EFF7C096F66DB31E05EE1E4047205129E0733344D5440BC571FB559377DC6B0BB566CF142 +ss = 68575A048C1E588D59F7BFD9CDA877D3CA23B93D35A51E9D07920859334AA036 + +count = 26 +seed = 7C33CA0E987226C8524DD56C811FA4D1CCF9995B1E4E4DD5B1481974E88CFABFBF6787775C2611CEFB27ED4403EA9B46 +pk = F5EAE45EEE5080570636B25B9A0BAD3FE2C66637A08DBDD6FC0D6877521F16F2C50698DFA67DA94D1A036F53ABE59AEEF7ECAC46ACD26AEA31C55515C1BAA7CC774D0789C4AB3EDD8546B29176E79FD33CDEB31A809A98114A924631E013BA239B4A35DDC01CA37AD78EB2856884EB79B33E2395F20E8664CF9D6ADE47E6ABBED67EAA4360929D11DF18B98AB2749F9AEF11B1408AA3EFFD73064879C246D0F4D19DE7C6161C1A444AB06D48BDF4D8B22A6B06F7F0E76D4E78C4CB64AFD6B6166D3B85E651A877342BB55E728FE899852C1C38F39553205739F303D2A55C228AD74054115D4F48F71AC9B2F044F0488406ADB9C0C71214C41E66B0C4D1FFD648FABFBFD1BF399A63904CCD446668DAECD0CB4A76BF6167C8B849EFDD41CA2D49824B74EB5BE28571615AD270DF81A01AAEC4F0CEE4C241392A1A45FD071345371C91D64D7E33C22CF3BA3157304686032F6096735899EEBE5172A1B2FC4401E58511458DB04E46F0822297D1FC163DC5D1240212CFEDB76BD6D5187DB27E3E2FB0022868EDC7657985277C8B48E51BB6C0D32D4A08DF40744C361FA92EAD1000DBA9C6EDE727AE78A08E3DE2315B5714111486C453ED9B5677CFAFFE726AC20E100C29AFFDF5334C72CC0F60686A35BF6D2BDFB0FF38B001A572805610233E193ED8492CE38D047CA1055AAD385FEE63F415FF6437CF70B81C8AC7E792C738C2358C474361EF6445388B6B955C5552ABE867E3956B0343D456D7C36C3B23A0D9C43292E1D306BFC34907F13AA4ED045028B0E260 +sk = 013BAB0212D04ECD54B478DAF72748003A25E2CB060BA6CC50BF95C292B8206B9DA0C5DA5F195B80FBB99C2E8B06926074F3F604B3F6195B5A5B9737876BBA72D4C62F5E42E737D461B40043E6C8A800F5EAE45EEE5080570636B25B9A0BAD3FE2C66637A08DBDD6FC0D6877521F16F2C50698DFA67DA94D1A036F53ABE59AEEF7ECAC46ACD26AEA31C55515C1BAA7CC774D0789C4AB3EDD8546B29176E79FD33CDEB31A809A98114A924631E013BA239B4A35DDC01CA37AD78EB2856884EB79B33E2395F20E8664CF9D6ADE47E6ABBED67EAA4360929D11DF18B98AB2749F9AEF11B1408AA3EFFD73064879C246D0F4D19DE7C6161C1A444AB06D48BDF4D8B22A6B06F7F0E76D4E78C4CB64AFD6B6166D3B85E651A877342BB55E728FE899852C1C38F39553205739F303D2A55C228AD74054115D4F48F71AC9B2F044F0488406ADB9C0C71214C41E66B0C4D1FFD648FABFBFD1BF399A63904CCD446668DAECD0CB4A76BF6167C8B849EFDD41CA2D49824B74EB5BE28571615AD270DF81A01AAEC4F0CEE4C241392A1A45FD071345371C91D64D7E33C22CF3BA3157304686032F6096735899EEBE5172A1B2FC4401E58511458DB04E46F0822297D1FC163DC5D1240212CFEDB76BD6D5187DB27E3E2FB0022868EDC7657985277C8B48E51BB6C0D32D4A08DF40744C361FA92EAD1000DBA9C6EDE727AE78A08E3DE2315B5714111486C453ED9B5677CFAFFE726AC20E100C29AFFDF5334C72CC0F60686A35BF6D2BDFB0FF38B001A572805610233E193ED8492CE38D047CA1055AAD385FEE63F415FF6437CF70B81C8AC7E792C738C2358C474361EF6445388B6B955C5552ABE867E3956B0343D456D7C36C3B23A0D9C43292E1D306BFC34907F13AA4ED045028B0E260 +ct = 53B8C4C6E1E780AB81F9FA581FED8F5E1584EA6DB40BFEDA8B021DCEBA806A110700918D1B334C1E61834CAC574F4FB9D71B1BFA489571A7EC0FDEB0039AF66494447F69A1100A828C3CAD38B9DA73AFF070023DD6C937BDEBD091286F5B13103C6416B77869EFE7D17CD3A9BCC09C210D959AF33604EF4537E34585052B2D192C5CEADD243C101C5F18818F54B45FAA3D75184DAB2BBEBA7F034DB3549FF47180541D91BA4212919138118A6DAF7F588D3E5D7AEE0F65EB87C83428F8BB810C7DB931D2D701F69DCB97512344BE4291E8051519DF2A678ACBC36D288D53B4123C18674B1505A123C5B49CE713E50E238A011248A67B3D034E189C7B2158CE4454E53F18673C74A972DA2EE18C508D19A9F5F09467F373A6D45C4844BB1910B54C3D8CCD43B6F89DA423FBCA2C87821B7D0E312AFA0D1FFFF59B34CB089E4B83236AB3F3348AB599E587FEF91E9DEA3842A60E55D8EA05E5BE617B00F40D7F32AB301BB07A65534AF8517ACFA4255B79279E72B417F7D71BF4ACBFAEE1A51FDAB0364B5644E652BFBA8565DBBA194EB3D2864EF5493F997FC96561C1ED6B8CEA6E03C8CCA6814017D55789738EC4551D00ED5E3DC9F6A64A238AC1A54480636E1B4AECB7CE0DA7328371B264B3B8F34BF8B1E53D055A926C4D86EC18774911F595C840F8E45CCA462DEBEC01E33E1F996E80419C165FB7164424D9B9B3C17843724DFC6A991A5AE3888A1BB4FD4D3DD87E911D49F83260E791D3BC42856942EDA482A97FD47BFF6F947B10A1880F210BE48A912BD54A85702A7225136950DD752E3D13ED87801B36370D749F527C56FCD9939778 +ss = A7E213A4F0A8DDEDEFB8028BA3573D1BA53051317E6D8E8C84FB1329F639FBC7 + +count = 27 +seed = 54770EA1252EA2857D6635151194F5F520ADEA8A41E409FF498D40C271359858FE2B084D5B96BEE087B8E8F4DD4E00C5 +pk = C9041DB1B76291A9412F1A96905CCC237FCF519DECE511CBFD98567EA8F310A676F9FB2AE1434B6E20D82B63CEE309D3315D35D48CBA901108506681B5FD9528B26DFE72D75B3AA14C16026395AE13DEB767ED105323F0133E3786D7F75326A83209D4F2A77C8EAE85C0413A5FDC07B9434A70637CD7BB97AB6FA646B4AD66FBC0989419E101E744CF8D580278E9CD280AF221B4FA48C6E651A8D6B46A8D827A9E69E71C210916725D05D29EFD1884599548A9A7F2F20EA35E019743EA31CDA24D1A6325A537B941C4D4D236E19A3591E7D903A136D8BE502B69351E7387B3FC5060D3C42C5AF9FA64D2EA91C1ACC41A1DC779928AC5EB3847CF884A9C707F0500EDCA4518B7AD7667FE3BDFDC3C3552165042F5F58A41D2D25C3B37EADAC7BF504BC19E7B737FDECCF18AAEF8CD7403954372EB741C2520D074B5FBD925D535C7EBAC5AAFD61306513E3E3B4B34B1DF1045A130361C4E3DFDD71FAE184F82ADAFE3C245C818159F11EEA3F3CEB7FCB50C2606211DC33511D819B7A50C631018EC9C9DEACBE64D59E22DA8AE52694008DB9A2DCC91402DFFCA41BD9080C784ADFC4E7AC2D6C95D502F97E8F74C38E9DF71284997F535ADC7DD17739BE535085C73AF7A3E652B977FABB72F64592AD7C932BC3428C10DB4B13F809A7961962A798FC6ACC2860F9D739BC0B78A8000ABFC55C60A801997793051649F83E768642B236588B4823F1BA27A3C81A8058E14D470842D0358B0C432512681AAB67FCE081037631F4E0BA40CC308C42FFC8D772A2D4F5E04 +sk = CCB073C4B90BE0AD746E26FB093B60C70110BD1DCBCDDB566A8CFFB7B3CAF80E71600A8982C350DF524CDE514431DED7AEC23576530894BCBF0EC0BFEF0BB64F8CCD7F321635F438F55A1BBA934FEC02C9041DB1B76291A9412F1A96905CCC237FCF519DECE511CBFD98567EA8F310A676F9FB2AE1434B6E20D82B63CEE309D3315D35D48CBA901108506681B5FD9528B26DFE72D75B3AA14C16026395AE13DEB767ED105323F0133E3786D7F75326A83209D4F2A77C8EAE85C0413A5FDC07B9434A70637CD7BB97AB6FA646B4AD66FBC0989419E101E744CF8D580278E9CD280AF221B4FA48C6E651A8D6B46A8D827A9E69E71C210916725D05D29EFD1884599548A9A7F2F20EA35E019743EA31CDA24D1A6325A537B941C4D4D236E19A3591E7D903A136D8BE502B69351E7387B3FC5060D3C42C5AF9FA64D2EA91C1ACC41A1DC779928AC5EB3847CF884A9C707F0500EDCA4518B7AD7667FE3BDFDC3C3552165042F5F58A41D2D25C3B37EADAC7BF504BC19E7B737FDECCF18AAEF8CD7403954372EB741C2520D074B5FBD925D535C7EBAC5AAFD61306513E3E3B4B34B1DF1045A130361C4E3DFDD71FAE184F82ADAFE3C245C818159F11EEA3F3CEB7FCB50C2606211DC33511D819B7A50C631018EC9C9DEACBE64D59E22DA8AE52694008DB9A2DCC91402DFFCA41BD9080C784ADFC4E7AC2D6C95D502F97E8F74C38E9DF71284997F535ADC7DD17739BE535085C73AF7A3E652B977FABB72F64592AD7C932BC3428C10DB4B13F809A7961962A798FC6ACC2860F9D739BC0B78A8000ABFC55C60A801997793051649F83E768642B236588B4823F1BA27A3C81A8058E14D470842D0358B0C432512681AAB67FCE081037631F4E0BA40CC308C42FFC8D772A2D4F5E04 +ct = 61334FA8CEF3D3BAF4E30CA17A4EB3D0338272D2034B539A494961CC802D42627C20E6241DF091A2F941B5FACD2A83E7D82A2664D4B4BD738C69AB7127373FEA4DE18BB6DD9E9AB327D62BA22C0D610329D6B011114F4105231D6E58DC4CD9BBA048F0489B04FE02F95C978E114C5514F1C8314C946564E6722972D4406E5135AA75DE815547F8C0E1BB22E1376549F61B0A5B4A6CA86A305CD7D300396F155E0172E4676D40F2F51D9D7CBB383E59C478475BEF97A4F3393609551D0B1B63A1A3862428B22A0A1C08D0DC5A9E0E29CAD7D06B48F418FFDBCAAF5684D430489945F8E572C3F66E58169DDD6023D8132ABDF304B96C94B6F58E2B22B90C418A6635ACAB695CE3B3E815731D9819FC1EAAB5E3997C00335FDF104DE13C8F085FC169A8047699618C2430F353183B1743B64A712EEF92816DDE4E9CE6F1E39162A2B83C2B4403AA504EE26957FD9A01A3BE98E95FA3CF84C858522C270BB05CBC421F5DF71089937C1F8F57A2DD0D83AC83E54C060A9CB2E819CE62E4B0434634B6020529CCC589030DE9848F7B92A4BDABDEF110109802F416FF95F4CBF201CE8079F1C4A8FAB7998D93F7A66D595A89FBA6B09DDC52838626E5C849ED954D53B10A488416517BE2F33DDEE8456D0B833B68009A86283424F9CC04E278AF9239340E328C5DE1D9C11AA9A4266A749A8081475655C687FAB74C318B0FAC0C340DE760EFE4B4327AD52AE928B7379172C7E607612086C8530E09B967CC0259FC9300B13921D2D37D48A5D8C2485B478D812A08F34C2DFED8E25A4480BC343AA5F58F45698F16FA7581558579B9D6E38DAE2717332532 +ss = 51DB4F6AD943370717E83479F265C1A3456334002DFFF6F52CC07BE5462772F5 + +count = 28 +seed = CD6CFE94E9C0A1CC4FFDCD2D7876504BE5F50F1D1CA5CF93482943465B268276056F2781F4DE805C138976CA72621387 +pk = CA8676FA2967729E49DB43D3A7CFE53C515D00B756F7F99D7F4E4021BA35F7DB1802C439F477A747CC4E2CB0DFF94B514F6F13F1B756DF218088F79416357256C5B43E21B521B2E679E11A20D487892CC821C5823CE7A978D6A307B6C33D8C9C50198DFC7B7175EA9779134DEAF25CD4F91EF9C721B0B21D51731FD46985009075B54EA5E7614F296A7DA87B6D1D6EBF2E23E452F89918233D08D5D0C7CCAD927B1DD0578D24E8DB2F4C6145CEB5EBEC9ECD2D75F22A2C2C591CC55160270481AE622BF2AB193B30C07417A02AB7DEF719BC4A9388B19CEBDD622C9DAD90FCC9C9C5D73E9038E6A48BB76DE7CCCC061D7480CD17FD0A5C5AFA71BEDB5CB97EA4A0F8FAD6F371AD12169BBCBBD9ACF6F4CC8135F5A54BDA93C616C6B09D73F4914C669350D8885E58A9C766608B24A246DC9C7C3CEB39BFA70EF20D75AB446A37F0A71E9C53D4FC78D41E7823A94B775F4AD66A200744F9660C85821E1CDA6AB07386578477C531D90FA5148967E2EBF1B51844553EEFF1006BA2CD045A64DBE93A06810699BED01A07001934F62E66383DE7008714218A4C29AC56FC45B6C104B054468FAE594C570BBC076D93F98F463716FF5D7475B9E69EDF1540BCE1ED58D8AA2992D0695FE8B07A4053B9087B4A5A7E1ABA9D4B1DF426349952FB5381E083F4B24A8A4D9401F7CD233F3645CECCF43361938202241141E8CD5F3CFA72DA990D90EC7237EC2AD18A44E051A2E1F146AF5B238AD4867574523664EF60D90477E963D97C0EEAF8482E83C709048F572CD90031 +sk = 2E889F44E28901E9AC7CA6B2FFFCB124C8979401B17064D7E1D51A7E3C3ADBFA0E145E44AAE52CFC609E6F47FD7A6F6AF877190FF52256D0AC5B05B89C3F449F48E7A944F02FA15EAF23A543AFAEFC03CA8676FA2967729E49DB43D3A7CFE53C515D00B756F7F99D7F4E4021BA35F7DB1802C439F477A747CC4E2CB0DFF94B514F6F13F1B756DF218088F79416357256C5B43E21B521B2E679E11A20D487892CC821C5823CE7A978D6A307B6C33D8C9C50198DFC7B7175EA9779134DEAF25CD4F91EF9C721B0B21D51731FD46985009075B54EA5E7614F296A7DA87B6D1D6EBF2E23E452F89918233D08D5D0C7CCAD927B1DD0578D24E8DB2F4C6145CEB5EBEC9ECD2D75F22A2C2C591CC55160270481AE622BF2AB193B30C07417A02AB7DEF719BC4A9388B19CEBDD622C9DAD90FCC9C9C5D73E9038E6A48BB76DE7CCCC061D7480CD17FD0A5C5AFA71BEDB5CB97EA4A0F8FAD6F371AD12169BBCBBD9ACF6F4CC8135F5A54BDA93C616C6B09D73F4914C669350D8885E58A9C766608B24A246DC9C7C3CEB39BFA70EF20D75AB446A37F0A71E9C53D4FC78D41E7823A94B775F4AD66A200744F9660C85821E1CDA6AB07386578477C531D90FA5148967E2EBF1B51844553EEFF1006BA2CD045A64DBE93A06810699BED01A07001934F62E66383DE7008714218A4C29AC56FC45B6C104B054468FAE594C570BBC076D93F98F463716FF5D7475B9E69EDF1540BCE1ED58D8AA2992D0695FE8B07A4053B9087B4A5A7E1ABA9D4B1DF426349952FB5381E083F4B24A8A4D9401F7CD233F3645CECCF43361938202241141E8CD5F3CFA72DA990D90EC7237EC2AD18A44E051A2E1F146AF5B238AD4867574523664EF60D90477E963D97C0EEAF8482E83C709048F572CD90031 +ct = 8CF585EE1F0FD576303E0CC13B44FAAAA8DB5D48DFCAE2E6A9D2EF94925AEC0B3E90E0C9C334DD3CAEF54A165630AACA5687F29F08A9917107C327AE4EA679A6BBFE1B04B6F4778D84280E0AA17E44070FAF412DD73B5E01B0DC98211F326692F33F217364113BDF6F3CDD88B69C69F080ADD60DE0FAE7D1E969A759422B65BC34386F3F496FFB3F3A595E59146A719B0F8EB571A3470D9006A811881E414CEA5F69DFE99A9819C7626D621ACD8D572A8638A862F8B9F0CC9DAF9503A64295D780EE6E0AAD1F9E69BA8E895AA8819D9E80322A3F3016D8BB3C3F6B8BC248AFF18D98B35F75A547F2E550CCA6D8B55AD75F246D03CAC89F85F9D38BFF04FD9E5604D5C758FF6B770D0D94889D7BFA74A808BB1083D7E994A22F28C90AD7D1F41C3E6AADAF8446D30B84467175A91F36208D1E24C1F527CC8497C00A6C99724C150245EADEE2B6B1B06B663C5C9D5372800DE382FCF19367B905A6767BF5EBD3E18CA89C39173BC99F4248AF5CD94D96327B2017FE9437B33A90179F0E3F94584B6E759B7ACB1666871D7F1B528C36C5B64F7ECF9E4EEF1ABDF03FE5E67BAC6CAC756915C0C1A0AF1101933787EE2451C40448EC7FA6A66FB63965E35B5095511055C030DBBF5081EF71B59D1548D8B93AB5389480D51210DE1369AD544A067D3537D25D3D9739388202BE14923A30A26254E7F84965C437000AC2CF967805F1449388F7307842BD1017BAAB4E2DBC31AFF187824AAC572566FB511CF7F84794A068631ADB1B755954B2A701B9401C2523029E622871988CE7098144F104944F8EA395D6FA72C05E04CCFA91506242D2D1EC1331B4 +ss = 9F8E75879E6A84A9A4B921A80FCD6D581EA2988939775C9FA8723516ACD7E164 + +count = 29 +seed = 265EB2DE7099E4BD5614E5DE7F0C2A05C78EF3E8E2DD4AE4CB70F3E5E59C8D1D88248303F07DE0C5508652DA66B47222 +pk = 5A9847CC18931582134223DF717CD4152A0FB43054ABD826ED890C09AAC3701D1D1DA5EF5403267D623B342EF98A8B6EA0955F645F6D7344F06BC2D7D5B5F4728F87563CDC7D17698F1877F05ED95E6787F49F33DAA6610ACC32CE6FAF2880B45E53144B3E8A25D1BF38DE3DD44985FD82453A1E56E15E3F7CB96531251BF2C9CDF9B6BDEE9C2E40CB34D1A2A44AC66B3DC39676A1177B8FFA7018A27C10D0DE9314A43AAA87B93D6EBB6BF21C3B5D727DE7E602EB8FA9DAC72D3804F6CA4EE35EE22D09ECC176487394B2BD20C35E8A704DF832E942225776B28191EA012461CCEA94EFCD6D3202DEF0151EB4A34E108781D09170A635BA67B80D29B77C6DE1B768A467F12FBA5587C3B1B648BE751D95ED0149F7EB3ECC3731BD917368555396A80F9EF9C8F94692FA09598B7D03338F3F0C63B76A27B8E4E89A5D2ECBB37D4945D992D811CB58A05612AB19E460D9E3F5C1C4398FF6B02882731AA4DB4F0447FA2AD399FF60657166D29A779714D0A18E12D71CC84167BE08136A4DB7177721EA3B37D74F169A7916B58AC52AC69164F5C0FD977B221A66244BE4CD9A5FC0DAA8CE33D2D3C03DEEEF00485117E898C4AFF436A35A171A3FF69B80EAC5ED6EC10B97F7E96F084FF8C71D50F2285FDE806DFB100F1A50DC543FF7D52EE7220E277F4D5D97C987893325A26815CD1404713FC5576CC1D94A2B34B23EB40EC9FBEEE7EAD2B01FA12775FE9B0EA03273EA64EF8459D6A0BED24F4BC51FC01D1EE2BA59DD5ABABCC446DF5F233AA7E160530CC3272D +sk = 174AAA36410566DC15A5E62874218D7ABDDE0B2C0F30D877BB80B1ABD5F5A0A450A7A2354F7E5CEFA6F4A4E9A1C411EB9364506E9E1204A8ACB3CB77FBD2C4ED186396657F35AA3708568C07E71712005A9847CC18931582134223DF717CD4152A0FB43054ABD826ED890C09AAC3701D1D1DA5EF5403267D623B342EF98A8B6EA0955F645F6D7344F06BC2D7D5B5F4728F87563CDC7D17698F1877F05ED95E6787F49F33DAA6610ACC32CE6FAF2880B45E53144B3E8A25D1BF38DE3DD44985FD82453A1E56E15E3F7CB96531251BF2C9CDF9B6BDEE9C2E40CB34D1A2A44AC66B3DC39676A1177B8FFA7018A27C10D0DE9314A43AAA87B93D6EBB6BF21C3B5D727DE7E602EB8FA9DAC72D3804F6CA4EE35EE22D09ECC176487394B2BD20C35E8A704DF832E942225776B28191EA012461CCEA94EFCD6D3202DEF0151EB4A34E108781D09170A635BA67B80D29B77C6DE1B768A467F12FBA5587C3B1B648BE751D95ED0149F7EB3ECC3731BD917368555396A80F9EF9C8F94692FA09598B7D03338F3F0C63B76A27B8E4E89A5D2ECBB37D4945D992D811CB58A05612AB19E460D9E3F5C1C4398FF6B02882731AA4DB4F0447FA2AD399FF60657166D29A779714D0A18E12D71CC84167BE08136A4DB7177721EA3B37D74F169A7916B58AC52AC69164F5C0FD977B221A66244BE4CD9A5FC0DAA8CE33D2D3C03DEEEF00485117E898C4AFF436A35A171A3FF69B80EAC5ED6EC10B97F7E96F084FF8C71D50F2285FDE806DFB100F1A50DC543FF7D52EE7220E277F4D5D97C987893325A26815CD1404713FC5576CC1D94A2B34B23EB40EC9FBEEE7EAD2B01FA12775FE9B0EA03273EA64EF8459D6A0BED24F4BC51FC01D1EE2BA59DD5ABABCC446DF5F233AA7E160530CC3272D +ct = F719B70100B299344369099E28EA4688DC1BB5B155B3E8FA8E61D4A6D970C3832D28BE74FFED3B742F83F3A14F8F8CC22C90606575C51F05AB191B063351E3C4E97E5385DFA2DA65AA6389340F2360F59E7B979490064BA118687C04EC619E5FDDE9DE109A89B7AA9944EC3C739CEC0D07FC26E4F15F75DE9EE2D92FB863DAFA371776FC5BEDD615542F62259987F04968436ECA4A3F672817699234B84E2183C373CA1DCE23336852F26CF2FAB9AB9A4A96839D5CCC2C42079A376326E6B0D8903F78641B80184990A1767C009CBA8EB2260EC2F8C2D71616B072BF2178BB0DEB460B34492FDA07652D482AE5B96E5FAB819BF80E384CA6A305D9498FF1FDCDFE38BCF1056D1D16E11FE8621883A3586DABF0DED14FEA1C4C0B987B761886C70CB63304A7019B129C13C53E58F9D83138C190D97B7BEC71A414EA7F9FDB69B2DDA964521D32C4269C9A8D2BC02EF552B7C51387641A812AADD8D6AB7F65157AEE2FEBA99342394275964D6C032BF54A54875BFBC697B3163618DCB5FF1C528E46C0ED57A6C0B3691157BA3B5C16EB5F6440C60341F36E4A27D807DA0BB03E7E156F15B477C9179D77DA75A6CDAFFA219F0CADCEB9FB71E1CCA4AFD6BF589759A8ACD016D34DB3800C7CBC7BA287F7B5A30A6AD8C767499533A4227C580CED8DF3619387555C05AB3D4D96D9D9159D9A1BC452FE60A8352BC5F5D557BB84718BD8FAEF34E795FC636E596045315FE8989FEEEA6C75F5E00318FCC2B3C6934E8BA3AE5D1DCC8B8C465E5161556ED4BC097B0A6A37CE1EF7213A22700FA2D85BEE01926AF4C5E387513E1369C072EB67C1E46CE33D +ss = 8531E180C5DF105DE8D5C100883A17B6FCE95F3CB7BB1C293C0EF16EA96E5FA1 + +count = 30 +seed = 806BBD111F27C2668318387BD0830F65EC21A51AF01985EF48D03D64E1958FF7EE5133A4EBF6DBF36329BCAAF65F40EA +pk = 27443052C1F1CDDE9A3C57FB146043878F97593B78DEEE0B8D4BB8C625BB7AF925CCA9810EE602DFC4A99D24613649EA3DD34F8BDA08D10E7970F02D39C1DFC055C15B4AE5C086CA81E8242CE6D69C108536ECC82DA2F602D3E4E3E00C1B819D5DC6A52209218723469E502FD450A3B5AA310FDAC2A944C0D743E5775D3FF42BCA5624647F52BB72C82F1A1FD77FB87573391003BDFBDFB1F1192E005FB5899E705AE9D5FE42D6E10DC845BE2B0112C8933EAF4725DBC59E26EFF72154DA0854A83925A41E8B7D23F4E724B75D5ECC86CD310239634F21EE7754BAB1DEBB0062A410D96E83B2D6FF7B21EF26EA64437ED9C47D85D3F9AB558BDECC5C8329359A12CE58A16552E37AB9C962E16BDD6767B62D23CF3C483F8300276B306AE091EE0E0D25A55B1ED28BF0CAC52B9FF273D2548BBD1359E7009F91AD1E50E6B88D2304C406F2FDD2FDE4450D720659132381F27F409E846D2759A64034C3E209AE021B2F1CB38F0ADB50049022D442AABDD6962E307BC23E70574DE10E327FF7EE4766C20BA17C5EAEC0E54A063995BC686D38EE38E935F1815CF19BEB97352F938F648A6CDB56B4D0A5EC89EEDBCFA8FCDEC0A7ECF200F991A5E91F16CD9DC30C190E59618303AFBFC5C881B48E83F5EC62660D6CA2DB1986D71AF5F404083A4DB2383E8862A01C72DAB99543107EDEA98A588C6BBFC9212C12B093384E53B69E1BD44B4FD9DF6A75BC51397723EA2402B7AF78F9C40D26870C81A3B97CA3E698C000AFC5E8F267F46B1786079252885F3665608756 +sk = 351FE4313E2DA7FAC83D509F3103CAF7B4C64A4D458FEFDF636785AC361A1390F072D9B5A99F9C7A0A011E4DC10F6B600D611F40BBA75071E7BEE61D23FD5EDA0FAC43B0E0050838815746054B9C570127443052C1F1CDDE9A3C57FB146043878F97593B78DEEE0B8D4BB8C625BB7AF925CCA9810EE602DFC4A99D24613649EA3DD34F8BDA08D10E7970F02D39C1DFC055C15B4AE5C086CA81E8242CE6D69C108536ECC82DA2F602D3E4E3E00C1B819D5DC6A52209218723469E502FD450A3B5AA310FDAC2A944C0D743E5775D3FF42BCA5624647F52BB72C82F1A1FD77FB87573391003BDFBDFB1F1192E005FB5899E705AE9D5FE42D6E10DC845BE2B0112C8933EAF4725DBC59E26EFF72154DA0854A83925A41E8B7D23F4E724B75D5ECC86CD310239634F21EE7754BAB1DEBB0062A410D96E83B2D6FF7B21EF26EA64437ED9C47D85D3F9AB558BDECC5C8329359A12CE58A16552E37AB9C962E16BDD6767B62D23CF3C483F8300276B306AE091EE0E0D25A55B1ED28BF0CAC52B9FF273D2548BBD1359E7009F91AD1E50E6B88D2304C406F2FDD2FDE4450D720659132381F27F409E846D2759A64034C3E209AE021B2F1CB38F0ADB50049022D442AABDD6962E307BC23E70574DE10E327FF7EE4766C20BA17C5EAEC0E54A063995BC686D38EE38E935F1815CF19BEB97352F938F648A6CDB56B4D0A5EC89EEDBCFA8FCDEC0A7ECF200F991A5E91F16CD9DC30C190E59618303AFBFC5C881B48E83F5EC62660D6CA2DB1986D71AF5F404083A4DB2383E8862A01C72DAB99543107EDEA98A588C6BBFC9212C12B093384E53B69E1BD44B4FD9DF6A75BC51397723EA2402B7AF78F9C40D26870C81A3B97CA3E698C000AFC5E8F267F46B1786079252885F3665608756 +ct = 54DC66569E7BE9D42AE680C6D1F9B1CB14A37F24EF88A7D16A76E1123CFABEDDE5BAB03A2845609E0EF6BEA44C79B4CF8EA4BD39FB44BA585026E9DA0B56348ECFB6DD4D90A04ABF1F5280507B0D3F6799E8D9E9D3D5C1A122927649C7658F90062E45316BDA1D51689FF484C0F664C7B948702A58615D49E26A15582C891B5E8410DD509745449709BC4F06BFBEC98909F3F4C1FE0FD345561A52EED671F3EDEAA36108A2D06D07A5E72817A13EBF3A66D1F16BE38D09F7BEA7492DF73F0B7B47834D6BB0F27A7BD51869A657D979D97C9723D37829E51D35CE58557C85B654B8110A344649BDE3535570BEDD6435A2878DAC592632872D5C292F3DDF8C0D959D726FA0A0E4CCD318345B5A6B9A86470AABF9E02FE620697328936AD4C3014AAAC6C77F594E2081642899288E35B59565821E7F9627598CA58AB990EB324F55847355A52D0E28FEE3D7F89841609768E2C623B47E77F7B88D6BF2CF81DF3E2234506097978FBEF2FC3980D924B1094E3BBF5AE494CEEB6BCA2D93F2A32D60700F6ECF13EDEDF2D0C392446704B14D78410BC336E2376CA94CDE499B1D266542B169526B30D2149547948688E1EE60985673A73FB14597DCF479313CA71D7F714C64AD2DE501F875A9DE1A4B62E0FF43AA284A13F847C0BE1D66112B9A0814F12209497FCBBE3AA6CFDD885A7F04227108A2C6956B2A295E09A5C5998DAB81B86008B40089254BE524E213BE9A8548EE7BF519CBDAA06758BA08F39B5B19284FDEFDB37D8443583AD66428DDB66853621CCE6514D1C1B367113E7D61DBB5093C79F83DF29DDB916D2EAD13622B58420CCA75B4BC +ss = 4D99061B6937AA37901AAED330B5ADB04694E8FCCE7D4347B75436827F2B250D + +count = 31 +seed = AD540A9CE816D6FB1661E5483C44F6FDD00C9E7BD1A8CEDA4B4C4D3697D4F78ED0A56954996CCB7DA96ECB8F5CB15809 +pk = 5035B9E8338D6017DA3C6A052F61A5E6B3B4DC71AC0E7C34709DB3C4CDDAC1E593B032F90926BBED53218D8DC76E32DF426C7E14A17A8259045A112DAA10B8ACD65007BC4751138F83557DB665BB94B4ABA4E0BA3BC7E68867C4C603F04FE7EF10D9DB71249D2493E12A00EF6B745694B7C30EBF4454554BBC5089E095DE0338FA0DB77CB1657CB63478D06215D823A7C57D75CC9570E3780FA1B89A75632B2DAD28BFEF52B9177EDAB702D08CC73BB1B514840589B219D0DAFB3E6109A1EDA8FDD1FCC14B78A32A22DF8335D3553E53951EE545B56D46CA6EE9CBD96332B0A22DF3E164C3C2EB05B7A80755F11DC89C7E7DB6920D1204C9C20C6FB483068A8CB7FE2F6A79D4D3D59D3C700F0E1BDB5BBFD82A590F44C30F506C13F368D193DC54158F846F5FC128F6ED950A517C9EB3A61A3CBCB9827E269FC42E4D1AB310717FB944DE3931FBE8D7CE4A0254DDEE448E5449DAEC1FE41E50809D95FD6FC82FC2CE08E4217A19F8A0EC04B6A588B1E0D80C0BF173E3E45EB739A2D2AC897325C0A2B4E7EF2252126F82B65ADFEC99335643D7408F6E2AD111562C487D70D93A1F7ADC9E92CE38BF0C0833BDE1A2F58CC6724AE59FC5F36A3D8DF4961D7D6C05EE1E2C8A3D793B7B3D5C9FC96632DA38936E72392D19EB89336D38C116D38F2BAB0CA7B8855C17A0CA1BD961AACF43E82C0002986C94443F029CB60279D020A273E29E70ACD6DA51F95B8608C11A53A167CF5FE198E1EC981FBEB68D8DBF540501F3BFDFE0DFD3CF82BB60FDA0663ABFFA41EF13 +sk = 9BC5315580207C6C16DCF3A30C48DAF278DE12E8C27DF6733E62F799068AD23D5A4D0A8A41C4F666854E9B13673071CEB2FD61DEF9A850C211E7C50071B1DDAD03868EAFC78673F68DF9B1128BCCB6005035B9E8338D6017DA3C6A052F61A5E6B3B4DC71AC0E7C34709DB3C4CDDAC1E593B032F90926BBED53218D8DC76E32DF426C7E14A17A8259045A112DAA10B8ACD65007BC4751138F83557DB665BB94B4ABA4E0BA3BC7E68867C4C603F04FE7EF10D9DB71249D2493E12A00EF6B745694B7C30EBF4454554BBC5089E095DE0338FA0DB77CB1657CB63478D06215D823A7C57D75CC9570E3780FA1B89A75632B2DAD28BFEF52B9177EDAB702D08CC73BB1B514840589B219D0DAFB3E6109A1EDA8FDD1FCC14B78A32A22DF8335D3553E53951EE545B56D46CA6EE9CBD96332B0A22DF3E164C3C2EB05B7A80755F11DC89C7E7DB6920D1204C9C20C6FB483068A8CB7FE2F6A79D4D3D59D3C700F0E1BDB5BBFD82A590F44C30F506C13F368D193DC54158F846F5FC128F6ED950A517C9EB3A61A3CBCB9827E269FC42E4D1AB310717FB944DE3931FBE8D7CE4A0254DDEE448E5449DAEC1FE41E50809D95FD6FC82FC2CE08E4217A19F8A0EC04B6A588B1E0D80C0BF173E3E45EB739A2D2AC897325C0A2B4E7EF2252126F82B65ADFEC99335643D7408F6E2AD111562C487D70D93A1F7ADC9E92CE38BF0C0833BDE1A2F58CC6724AE59FC5F36A3D8DF4961D7D6C05EE1E2C8A3D793B7B3D5C9FC96632DA38936E72392D19EB89336D38C116D38F2BAB0CA7B8855C17A0CA1BD961AACF43E82C0002986C94443F029CB60279D020A273E29E70ACD6DA51F95B8608C11A53A167CF5FE198E1EC981FBEB68D8DBF540501F3BFDFE0DFD3CF82BB60FDA0663ABFFA41EF13 +ct = 8C5994830D9C80551BF3B5D90659094F08EF4F4D1018C17A49EE957E0CD78A96E6D80D6F0217CAACCC36980DBEDE467144B242A9D8C5E981E9082612D6CDE5B13A9FB234C51EDFA16462A4E772CB022F2B1ECC65D4BA20435377C6621D0D75677EDF0EC01E8775919A2843F0599A652F9C8CDD989B05CC7AA74D2C6596F41623DEACE6E82B0F4CE54D9724777DFCEF0DE62D40E29827B9CAE758EAD7C67303375175B206CCD0F79EF82F51A4FC65D9A264A7015ADDA10B3A9F869E6161C87F89283B64AA25B5B644842DBB55894632A262955FA0C8EB0132745B553A0AB5772F8EAAD80B1241DE3BA65D619EFC66B6B0AE506257FE30398D3DC7F444A5CD5B4E76D7A6AEC2071A49896EBA1AC2EB1D09429061BFE227644E4D1493F6B7747338EA1FBB23859D5CD2F835EF013279FA2ABFE77E0112A153F4B31D64604E0FF86558349268351D79D2451AA923A913388757E522650BB35E882157BD9C1BA9D1C99745A4FA7B2F24F5C88BEB74803025DCAB386EC46DA9143B006B750F0D303E64AF5434EE916A0DE6D2919709CF59E26922341DB12A7947BFC9AFCB02231AB316563BA5F8E1BEF2FF114A6A80E72C53527EBECBA9FFF70FA406949253C79B2C8CE4DC53B68C4F7A2C435873B6C0A2B1AE54DCC0771564EE5155AB0F5EF2B79804859AF51C3F02FEDFD03503FF0273DD6632D542AC8920ED9E7C420DC064C0469923DDE65B7214345D62BFFEEB5307ECE64BDAAC14D158422047CF6430FA508D914AF82B69E8122890F5898BF2ED77817D29ACA346AA2082A202BC5855018A7826005807788092CF9C9541203634474A775A950BDA +ss = 3A328629E9EA491DD8FC925AE18FFF3E9C2CB62291FF4AFC4D4812D08A4CB508 + +count = 32 +seed = 288A5F2684D862A86D2790AFDDDDBAC6FDA934EE7D2E6DA1508BB550838609E8107312B28E00A6C01706374CCD3AEFA7 +pk = 6F9B51F984FA359492D49673FB6B0B4F3DBB40F9B7FAD4DCFF53CA0027A90C159A4D194196407A5888677ECDDD1EDE91987B88410807D1FF7778381D0093E146C97ADE11665753046DAA71D7B1E73ABD6BE162EDDDB38FD27942951B84612CDB4CB6C32A8B9F6171F882D253054DA25C1C4EAFCD2F32EEFB44ECB4A0355277A53D2B3A2F09EE39C1FA6E3D72C496CA6FEABE1612BA779687AD0BB931D3764C6151C96A423972DBDB95C9C115F5FAF805B9C30A7F5056DCA4DA368160D86DB81C7693B85DA7E468B659F8E59EC29817630F6B955F5640A1E96DD40C9FD24AE070A851BAFA6E5F54D036BDD2033C07758AC12800E95A7198206B60F82ECEF64DA178D120362CF1479A11B6C59A1DB7D09112506F6569882A4F4E3A70FF6F097DF51EF518220146D6D910649DD95721D109733468BC00DC4543932416A78842809E9B3EF5448CC6D6770C983051679F4CE6C4055ED25BE28F348F493DD0ECA587E804DA23AC8D36A4E28E7F66EE31FD4D4501D08F913C77BE3A903EAE62A374D53914E634B22739F90CB5C2CDA474E9C57C1141239C1BD81A113B80E76DFFFD302C3EA3D96DF9DEF164905CD7EC114660491BB9A71E61103DF96E4EEF8C7A40AA2A56B84455BC9B2F67CB40FAB8D9AC2FC89C1E76CAAA6A6D524902EF6443884AA88421C695166B293D98BB51260B84CC765AF1DB263297F644872B9D6A12883B1796E125E5E0B0FB555FDBC12DEF51C4120378AC743E04A1B15198092A573A21C600813875981B5FE991ADD615C13B79143FD49B1E +sk = D8B907B34D152FF8603B73051F772DAA71EB902C47B7E2F070508269D757E02E36B817736CBC5F7B1DD6EEF5FE6332FB1A598F3871E5470D440FD2EA631DA28A947AF66FBDDFF91068DB66AAC41540006F9B51F984FA359492D49673FB6B0B4F3DBB40F9B7FAD4DCFF53CA0027A90C159A4D194196407A5888677ECDDD1EDE91987B88410807D1FF7778381D0093E146C97ADE11665753046DAA71D7B1E73ABD6BE162EDDDB38FD27942951B84612CDB4CB6C32A8B9F6171F882D253054DA25C1C4EAFCD2F32EEFB44ECB4A0355277A53D2B3A2F09EE39C1FA6E3D72C496CA6FEABE1612BA779687AD0BB931D3764C6151C96A423972DBDB95C9C115F5FAF805B9C30A7F5056DCA4DA368160D86DB81C7693B85DA7E468B659F8E59EC29817630F6B955F5640A1E96DD40C9FD24AE070A851BAFA6E5F54D036BDD2033C07758AC12800E95A7198206B60F82ECEF64DA178D120362CF1479A11B6C59A1DB7D09112506F6569882A4F4E3A70FF6F097DF51EF518220146D6D910649DD95721D109733468BC00DC4543932416A78842809E9B3EF5448CC6D6770C983051679F4CE6C4055ED25BE28F348F493DD0ECA587E804DA23AC8D36A4E28E7F66EE31FD4D4501D08F913C77BE3A903EAE62A374D53914E634B22739F90CB5C2CDA474E9C57C1141239C1BD81A113B80E76DFFFD302C3EA3D96DF9DEF164905CD7EC114660491BB9A71E61103DF96E4EEF8C7A40AA2A56B84455BC9B2F67CB40FAB8D9AC2FC89C1E76CAAA6A6D524902EF6443884AA88421C695166B293D98BB51260B84CC765AF1DB263297F644872B9D6A12883B1796E125E5E0B0FB555FDBC12DEF51C4120378AC743E04A1B15198092A573A21C600813875981B5FE991ADD615C13B79143FD49B1E +ct = 923A554619B2B73E9DAE41AD2EE2FE363707CEFF1ECFD1C0CF2C981102ADC32D0D720EF47BC8F43FBD6B86038ECC0CDD554EED4EBD061211E009A7E0E625E0C5B5BF4B0FA11F8D7D28720DB295561CFE025272F36F9752C88E9E4EB3594E9CB06021C7A5AB894232847E07A0138CEC1D59F24A378F75A0974FFCA0DF9AED531E6B24D9AA458F65AD505B3AC873FA578328553E39AECEF4956C787B0B37FD7AA0E8F6448C1F873E3CD1FB449EEE5CCCA478DAF13C38B90DD3751CF34DC8189393F6D636EFAD72EE310CD779CED4FB8E06A0786F603BA921CAB799AE9B364C467F85877DB3C37EF309F0B65E29A863D039B2EE44DFABD9D7757AA02E915A498FF354DFD896EF25C193C4D5E0651560EF730077D4EA9D794615E71CED5D48CAA04972FB8704D1A57FA84BDEC72439FB9AAA4AA4561F035449021489067D1E96CF9B52720A1A66AD71843C9E94CDCEB9D264C414020E26B25ED953A4DFB516695705C9F24E4BAC220DB39B8A4E6A30E31C0C82B26344A911C66FA7DC7588491D5C083C985D949034E9B245591497EBEDC1752F710E44FFB223D53633C879FA66172F171404FCA47A4170850AE886FBDA10611CDBE6A3B7B14CDB9A7402F4BA9DAE7AEC3D03BCD12CFBF07B798B3D8BB8DCDD37F6EB9AE33B012C50E5C9C108C88B0CC28B0034D003333E420D0AD0A388900275714BA533EEF0ED41D6C5CBDF30F352B9367771C288EE1ED570D4D3FE2C4B131C1AEC682C5196DBA3551E2413AB8FBB00FF85F224905004E8ACEB08CE2726C45C335E559C2130B4DD25E4A55A27B5ECAAA195D92C77CDF2A5AF6A12643A12D5F80DEF89 +ss = C8F7F0A56DB64B70D4EE4A22263722C76D1AB9178B707DFD931CB81D4906F258 + +count = 33 +seed = 4635DC5BB92EF98CDB6220DF0DD717C7F8158375EAA2B78FC3F0B58E9C9653E92684CAD3461D9158A481DA3D14694C44 +pk = E1074A3F19DBC2207FE11A7B2E4DC0A53C5CA8223A737CCCED74B952AAA644919F4F965428D95BC3203D51BD3C66E12D6E8DBE9268BFC8C45351C001ED9A836E2B5DF3B546F80FCFFCEB81216D8956DA7C79A9BA5CE61726ED6B229D530CEB810DDFE273FE56C7E015F5669C0FD5C2A703C7523E831C9DCEF4266AA2CD3E8DA31615598325867FCE54596DA09E9DF2EB284678782D7819E83C6E75869A813DC0F2EE77ABF6FD41FD45306E48AB36E275F8CA2D4816ABED52E101913DDC8910AC31458436F38BBDFD7FB55411A17D9AE9645D7F91B543868A0EB1259CC9464CBA7F50AF47C14B7E341F89C4C4E55840EAEE3D2C116AC934BE6C169EF07AEC8F94A97AE08BA81AAA7A67D718E2A6D7DC82858D21D4335A79059051AC5F76B26BC1BCB97F7DD9DEC150B1B237599AD7B53B3F42F6352337CA5D2BCA15798E00FB2954481262A0DFA370DBF40BD9D4C70FE7FF5065A7C8C848CC9FAD691214E8DCF59A272E686C59AB68022EB208C3D6B4888ED128B3462E7C5FABC97CD957EF1BA0445608CC3D2D22A8FA3348105740A8B8DF69C54678AC29D382FFEBB189CB244B3CC635F8C24494AC17E2C04301A91BDA36CE156F50601DB2EFAC98B2E29348381DC117BF55B04116749CD79FEEBBB9211826629F8C1B89E3B55083B88402B0DCC2E4B4F75E080085B92B82ABA1AFC236681CB69CC0CE8A51DCD7B779730EFDEFCB423AD4AB5EAA824BCB68A6E587A6CABC91C9EA0D77F37620B490E7F620A2BC6834BAFB26FF8F72ACF52E9BAC457251B104B544 +sk = 684A29E4E5480A5F2533E1526B5FAC8CDF5927F3D85087C71F928C59690EB56575D12195EC32A8686D0600E45D4A7F54219B0D7A3826D193A51B9156ECF2EDD630128521D62DBFDF5BC133D4EFF12A01E1074A3F19DBC2207FE11A7B2E4DC0A53C5CA8223A737CCCED74B952AAA644919F4F965428D95BC3203D51BD3C66E12D6E8DBE9268BFC8C45351C001ED9A836E2B5DF3B546F80FCFFCEB81216D8956DA7C79A9BA5CE61726ED6B229D530CEB810DDFE273FE56C7E015F5669C0FD5C2A703C7523E831C9DCEF4266AA2CD3E8DA31615598325867FCE54596DA09E9DF2EB284678782D7819E83C6E75869A813DC0F2EE77ABF6FD41FD45306E48AB36E275F8CA2D4816ABED52E101913DDC8910AC31458436F38BBDFD7FB55411A17D9AE9645D7F91B543868A0EB1259CC9464CBA7F50AF47C14B7E341F89C4C4E55840EAEE3D2C116AC934BE6C169EF07AEC8F94A97AE08BA81AAA7A67D718E2A6D7DC82858D21D4335A79059051AC5F76B26BC1BCB97F7DD9DEC150B1B237599AD7B53B3F42F6352337CA5D2BCA15798E00FB2954481262A0DFA370DBF40BD9D4C70FE7FF5065A7C8C848CC9FAD691214E8DCF59A272E686C59AB68022EB208C3D6B4888ED128B3462E7C5FABC97CD957EF1BA0445608CC3D2D22A8FA3348105740A8B8DF69C54678AC29D382FFEBB189CB244B3CC635F8C24494AC17E2C04301A91BDA36CE156F50601DB2EFAC98B2E29348381DC117BF55B04116749CD79FEEBBB9211826629F8C1B89E3B55083B88402B0DCC2E4B4F75E080085B92B82ABA1AFC236681CB69CC0CE8A51DCD7B779730EFDEFCB423AD4AB5EAA824BCB68A6E587A6CABC91C9EA0D77F37620B490E7F620A2BC6834BAFB26FF8F72ACF52E9BAC457251B104B544 +ct = 5AB4243D61312DA48428CEC4F6ECF4F76DF54345A443303654880F0A0BA641C289A33E354E0DC39934CF97B4AF8ECB127DA0FC334535B56FCBB4ED4A0138C4EE909BBBFBC17C51034AF28BB353A4A9DC50AE10D3A752A87AB659586F174F476EF23F40263234F9FFD6F3701689DC5BBF12334D9FA9F83C10F8CE051161732FF1E806580699F29FD3EB76DACA01AAAA85468575D9177D959BF95426B59935C52431989E694E1540BDD2BFBB09D0EDE26E1CD9E4E11703AD4A4243BE36FDAC42AB395D2F0F0FE04D7F106B4712105DFF65417CDB7AB8C3DF50B3084417EE359D8A814345E652D1407F279A6E96BF81FBE1A81C65F80D02913D9CA5A7B38284895CDDAD9AF231FB25D6EB5CADFA12571F4E3B3FF65FE590CBB1B83AFCBD57A8D1A8C5E910959CDB20666168ADA02A8CA4E69983500E29DFF349380C9F14CAFA7E56CF12D1C4DD6D23E0FEA3A4F6303CA5956E0C1144D81F65CE8B2AC7E555905973CF874DF077B1429A644861CCAAA0F0B41BFA0E1D8BB08E5EAE08AE77F3BCEC88BD379BCE70BF67006F69A4FDCFED72988C1BC4A6E7AA2958FB73896F4ABB8CD493ACE54339AA4FE6FCAF8F8FADB5432AFAD26685E623AD8E5A865A6E79B858A532526BC24A83E6FE1AB3EA6240898EAB62A73E9C8F34DB059E2CA9FFC2DA100AB620CEB8A474FC036D8FB5B1405D07303368173DEE35FD8DAA2AED79FFDB124AA9C44E484BDDB239BBA2909054A8FBBCE89C298413733DB39E638C51B45B81BBE02B3555043FF6097B14621BF16A594E8CF12D2A43655B029BD7BA0E021CFFD3C60458DC1EB561FCBDA2BE5E0035D0997E31868F +ss = 78696DC7DCF46923FBEC1AED5FD2EF9DC4FFB8045BCCADEA8D7557BC301E756C + +count = 34 +seed = 5DA2C51B4ACF488C8BDED5E985CC4702E4A7BCB248B5AC18AABA529F7F9CBF30EFA776E99F76D5C1686E94F50FB57DAE +pk = 9FCBC1354A4B69594486DBE040223865771590D6E5EF60FFB247E737F14DD39CE54764A4CFBD72A23415AFC4CCACC6135E5BDFEFE50EF0A5F8AF2F5DE204C2AD40F606B24D97CFC9E326A20CB982A6317A74B99CE71BF5A09C0E6B35CD2F2E3A645F7C5E94BAD3302C3587D28CC75AAB87D5D13F523B7754F9FADA02173979FEA05509E3EAAA9FDE220C57A03B7FCC0035D9D642C622FE547E7C7E43B337751766534A8D6F70AD32EDF9951395BEDE1EF9523DDEEA7008AB4B05826D38C22B82E9729647496E98C57BA2898C83C293F92D88FEDD26736F4B054DAA45F1C65883AF372719132B66627FB146A544AAC83F2EA4E5CEAA25BE93660F1F11F91B86BBD34DD5F412C64CFF65B8972240DDCB1147C35FEAA292DD5CA720F055121BD74F71820E7726C728DDABC4E4A29C825FF4FC7C7FFBD5B06BD871E9B133CF8FCC5F8E83C1BE3D3F29272B200A1382D1DBD5D156739BCBD8B67C06C5309CED5FF7D79648B93EB9A735C6389D50B021A36E91818C75789A33E844BDAFEF0ED9BC8DF791AC66DDC768B608556D3B8B68177A36D040CA2A492E048AAAA85E948396E4BF008145B328CA22E00F259B472437E89AE56CEF085D15FCE059698F290363600EB4BC375CD8A94D957612F1B9630A28A0B462144CDB47D52905F1A8CEA02EA532267FE003A8E4685F4716ED14A401A72CE2253B480A55852618FAF3E1FCBF37063AC8AF7E6819260AC93C5B18675DF45AC0648FDD805FB8C1BB9BCC81B223FDD8E75A02D8858B4FBD1544E2CB48D13BFFBAAA420B +sk = D76B3573F596EB286AB5231FEEC7499686B13021BE36CB126C7EBEB9D7030DAF248C0A21EA0BB6D6F56F12300E8584D8E9A34E0E6F52227281151AE4C305FB8FB2894654A15EBA3520C53320159D1C039FCBC1354A4B69594486DBE040223865771590D6E5EF60FFB247E737F14DD39CE54764A4CFBD72A23415AFC4CCACC6135E5BDFEFE50EF0A5F8AF2F5DE204C2AD40F606B24D97CFC9E326A20CB982A6317A74B99CE71BF5A09C0E6B35CD2F2E3A645F7C5E94BAD3302C3587D28CC75AAB87D5D13F523B7754F9FADA02173979FEA05509E3EAAA9FDE220C57A03B7FCC0035D9D642C622FE547E7C7E43B337751766534A8D6F70AD32EDF9951395BEDE1EF9523DDEEA7008AB4B05826D38C22B82E9729647496E98C57BA2898C83C293F92D88FEDD26736F4B054DAA45F1C65883AF372719132B66627FB146A544AAC83F2EA4E5CEAA25BE93660F1F11F91B86BBD34DD5F412C64CFF65B8972240DDCB1147C35FEAA292DD5CA720F055121BD74F71820E7726C728DDABC4E4A29C825FF4FC7C7FFBD5B06BD871E9B133CF8FCC5F8E83C1BE3D3F29272B200A1382D1DBD5D156739BCBD8B67C06C5309CED5FF7D79648B93EB9A735C6389D50B021A36E91818C75789A33E844BDAFEF0ED9BC8DF791AC66DDC768B608556D3B8B68177A36D040CA2A492E048AAAA85E948396E4BF008145B328CA22E00F259B472437E89AE56CEF085D15FCE059698F290363600EB4BC375CD8A94D957612F1B9630A28A0B462144CDB47D52905F1A8CEA02EA532267FE003A8E4685F4716ED14A401A72CE2253B480A55852618FAF3E1FCBF37063AC8AF7E6819260AC93C5B18675DF45AC0648FDD805FB8C1BB9BCC81B223FDD8E75A02D8858B4FBD1544E2CB48D13BFFBAAA420B +ct = 55D450EB9D7BE460EB7F76CE0C87469BA350EC024548F10FC08A668A0A6A4CD5CD9E118788781EB8C4C9DE6F5613DD6ED26E83444EBD71A5C1380469BD05DC6C93D66A9AC785BFEC1394EF2E7E7A5773AFC72044C67ADD4E1BB9F1C6F325AFA7FC03182988AC2439A6613FDFB33CE0698F6BE07D61C360C5A6B9B4F8FB27C3F233DC5EB67EBB911CDEECC44899991FB482FB7FB683308B9D59AD58CEBA40DF68FB960BC7D5519DECA5617F494F9A4BB4EE4E64CC1883E91969CF5F1EEA66C923C59723EA6E4FC1BB2DD8A4954CEA6602B307A9318303EC6D64847FFC077FC69C5329B84A17231D82B2B2F36DC6A9E9F580255DCC6408629FB585465B7747E5195A9CD9664AA4F3359728697C7D7C4C2D1DBC98CD21089C314C05FC3F0F53316E6590203E6430CF9580A7423E2A770629FBBD44C3998E636F49A9D4A8BBAABEB5D182178C1CE1B2140C0C5D729D5948E61A3970D0C35C6A49B2E46DDC5C49E20F9A68EB5BE01AF59EFBED03BC9291DC8870D5270CDFF753684556A61B8B71A7EFBD77C58FECAF31F8A39C3893CC1F09A3531851D7C181D2FF5406115035CEFF5FA2B2ED3C1D5D61C9FAF4F37CCF25DC764521BB3B92A1B449ACF62A94EFBEADBBCB5AE711A3FCCEF3675F46A7A70F79C00F9111A9745566634FFD175DCAF17E617F8BFAF4A7A3A3E83F03F6D2D8B39A4AE74859977E6903449993A249735F46D8B5228FF6F5C86BA4582B076244714BC3D237D08D47E3FDB6F853ABD9EED5C6E2F0C865FA68E236B64B569EB81FE8407F2954C336644712A846783C8A07CAE155F21C08B64CC95DA3F599E075A7D29CEA753FCBF9 +ss = 41F998F447908AD3448A348F8E73441FBA26717A83C1306C22BD8BCD4F8A525D + +count = 35 +seed = 4D2239E84B052109A78DBAB6D80C51A86D38248105970476B74A0B78B9CFAB6283E30D5A406FAE1C7F54F8BAE1110EE4 +pk = 8E867D9E56908C869710BE6AF46CC2C8DAAA135B4ABDFCE4920D436E839B9AD21DBBE6EC16DA4285B730B0A644463B52E5885B49BB05DE410A288DD48A00FF9F5A5E6DBE37A518A03FFEA8EB769CC28E791E9DBF468B9DB9A7FBFE440454FA670DF7D44CD1EFC45A5873BBC2B1B98F1BE580CDAE985CCB6E3089D0022AAC98160F316D25B9198D148ACE72F16BECBD34C3C77CF210C3E7FFC3B9E3B5AD1F3084A3BF7C37B791676044D544BC6375439530F4BF88F268C1934917C23A291F78CF68F575D0D7B707CD24E5A33EA46CEC8577A3BA3C1A6B954C50222AAA1FFD5D515B979DEEE2126A0B3523E40AC2DC5325ED9432AFC8FE4BD8C92691552D882E0574EC29DA90D71C912792309DC8D9A8F190D7B023D69290C656600E4392F3BAC09A7BDE77BD2EE1211B4AD1A637A814D961A7AF276D10B20BB53864B4229733E9ED94DA4FDF4B1FC8AC049B63DB50361057456AD0F82E309B80C5C6C079DEAE98C5B5911749F2FBFF508CDE146B14A788192D10521EF34E0F83DE1DC45AE3365EDC063AC71A7D17BB1B489BDAAF5C5078C42976C8BB1FB013475A0D30AC37CD23D4536B0B573F39DE5A8F0DF97FF72CD8569973C345DB1050E012112A7401C06473BB4C5C45CC1F545F0D92417D9230F6D1368F9C922742361E274FFE4183299CFFCFBA0A9E0268F03EB098BDB9E1C6E6E3EA317CAA02A3AFD136CB9FF56B1A3F72E1665C6924AA597A0F14F88DC461CA6C317021FAAAF41CD4836B45DC154795E43A2D5A93A11B9369ED9F7DF695F06475EC2F6C +sk = B87439FDE81C9E39EEBE7CF741C685785532C1DD23E8EF868B9CE7A541010F3D1646460817A0FCE5836BDFE124A7448E7ADF7B8ECC2652AC6D280E986682DF7100815AA831A61B6869EE6E7B2CA637028E867D9E56908C869710BE6AF46CC2C8DAAA135B4ABDFCE4920D436E839B9AD21DBBE6EC16DA4285B730B0A644463B52E5885B49BB05DE410A288DD48A00FF9F5A5E6DBE37A518A03FFEA8EB769CC28E791E9DBF468B9DB9A7FBFE440454FA670DF7D44CD1EFC45A5873BBC2B1B98F1BE580CDAE985CCB6E3089D0022AAC98160F316D25B9198D148ACE72F16BECBD34C3C77CF210C3E7FFC3B9E3B5AD1F3084A3BF7C37B791676044D544BC6375439530F4BF88F268C1934917C23A291F78CF68F575D0D7B707CD24E5A33EA46CEC8577A3BA3C1A6B954C50222AAA1FFD5D515B979DEEE2126A0B3523E40AC2DC5325ED9432AFC8FE4BD8C92691552D882E0574EC29DA90D71C912792309DC8D9A8F190D7B023D69290C656600E4392F3BAC09A7BDE77BD2EE1211B4AD1A637A814D961A7AF276D10B20BB53864B4229733E9ED94DA4FDF4B1FC8AC049B63DB50361057456AD0F82E309B80C5C6C079DEAE98C5B5911749F2FBFF508CDE146B14A788192D10521EF34E0F83DE1DC45AE3365EDC063AC71A7D17BB1B489BDAAF5C5078C42976C8BB1FB013475A0D30AC37CD23D4536B0B573F39DE5A8F0DF97FF72CD8569973C345DB1050E012112A7401C06473BB4C5C45CC1F545F0D92417D9230F6D1368F9C922742361E274FFE4183299CFFCFBA0A9E0268F03EB098BDB9E1C6E6E3EA317CAA02A3AFD136CB9FF56B1A3F72E1665C6924AA597A0F14F88DC461CA6C317021FAAAF41CD4836B45DC154795E43A2D5A93A11B9369ED9F7DF695F06475EC2F6C +ct = A1E91EAE0CE9B298BED7E2AF228D07D9C547B63079B1451590CBF1BE6818901B512F94CEADFCB8B1300A22D3390BC77B2BDB7D43F32C190D58B6EF0F8F678EB3CBB6AC2755AE6D4A757E8717D8AB7F488A8E0B6E68CC3BFE73EC7C250B378D00CA952DEC0B79B14A3FBEFBE908EBD7AFDE755E04C58E7198D8E2659E01AE8C80160822FB656D1D9C8D935866E6D403CEA329B2C2495B4C60E1E3C3657D7DF26AF467D7E6C1010920E2A4161807B31EBBDFC2185413BEEB6914C27118803C5043C67E42B3A90CF27F79AB19E969B43843FC2FF0A78F46AE1E4E3A1EBB34191A47F7A1BE62CDF2664D9671AA2F9E1116747E9BE6DE5D3D3563D99C1B4378B78D72B246C00153A558B52AAB09FCA457D3040F6D1730A915B2BC1F5C325E618AA62FECC41C67327F92F3F2863E4BDE8674622F1E74F11924214DFFFCC43F07AC2E3DAA9AD0BD9855D418E569CEB3C9E7FCB80BA11BD9DB14A606039551058E17252C87BCE9AA853C1303895BA448837A50DCD5DA17599F10A5676785A42D1FFE3391EF96551A7FACD8D2D3AC9339CAF9C73EBA6858D515EA90B172C7B524AAC36F74A21568F769582F7820593563DE8F61670F669F88BCE418838BDBEDEB937BB2772D7F8690F536DD9B729340D15A8F0A088A7FC9D7540B96ACF01151871044D3D727D837A14EB0A68A8A46AA579E0E3837A5815D961347134279195155D7D927A4B0BF48B1878714B7646D2C47E5FF194D4F3E645DB7A1162745993243BEF5A08E362E678ED770AEDDEBCF4E3335B08D15D7F9CD5506F385E6B50433E768D5C7B0F7E100DD31534648B2FFAE587E806FB13ADF038E +ss = A03F8B99F2B60AE8EC6679DB247508197CD8AC61735605BACDBEB15A320BFFAC + +count = 36 +seed = EE762F5C9021C36446706A88EF16312F4A12C725CD7AFFF1484337C91EDA8E89F7007F3705747D29907B3FB7500E5074 +pk = 720209A2E76F0312177438B8D22611EC2CE360C6206CADA64225D8AF09AD7C85939FBA1C2B59FEF265726496917AB7A803BED112FF1DD14FEDC9DAD6DAA78F986305FD777CB9CD98FBB628E60B080A526CB69AFA91D3FB94EF9728396331209AF0C0D7E65B9858CF932701DF8E8205C598C4B911457F2048486A52554BC55360CC21ACB1DDE3EDCC97703291EE2A5DB544B0BE185CD380ACF509BFF3892AFE7A38840984C444D5CC6E9A9DDD3C8886C0D4AEEAE2AA8AF34486CED02F3EF468FBC8B40FF56E2E255EFA6D31D989F73D85FCD74B6D0EB95A2B55309AED92D4A311F6980E9C91B015047EBB45413794298CCC3910055BC771FBAABFAD11BCE3CC524D0A5F3249398AA0FE139D398E43F519447BF42DF7A9CE34E24DB290159017149DE05556D662548C90131308BDE61B2E14F49C9A8F79100FB44B4C182C03EC9A4443BFDB3DED409B62963A711FED8191CE26D6F17B69889F10EC49632FAD9816AC75BB8C96895F6ADE175A7507D38C10CB37A72504B89C047F63706F6B4DA04CFA805D291F84DA600FB94D4950EEC077150788177CFC18874F528C8962A2BA12336ECFCBA5BFDDAE0D8CDDDBDC90542F5334FC9B5754BCE7F55DEE1249D8695E6C07DE58F2AFED87C50122F0C40BD5BC0A2C47FDD346A5E7E883A801CED84B9D8EF76DAA259785C8039FAC1B82F9E25432BFDB429026E93D814984C74568A029FF0128CF9E5ACBB293580F8DA8E9854022103E5084F51896A0A09F4FC1517CD2274DCCD9E2CE15AF82A4EB6557A684C3152F0716 +sk = 056661B38038DA4FDD7426F32A81576C73ED84843B305168A374F934E27A4E1B79238A80DCFD7C992D84B2DFFA67493E669243D4FA38C46B090BDF86BC548411A77127B247925850220B0BE970AA3500720209A2E76F0312177438B8D22611EC2CE360C6206CADA64225D8AF09AD7C85939FBA1C2B59FEF265726496917AB7A803BED112FF1DD14FEDC9DAD6DAA78F986305FD777CB9CD98FBB628E60B080A526CB69AFA91D3FB94EF9728396331209AF0C0D7E65B9858CF932701DF8E8205C598C4B911457F2048486A52554BC55360CC21ACB1DDE3EDCC97703291EE2A5DB544B0BE185CD380ACF509BFF3892AFE7A38840984C444D5CC6E9A9DDD3C8886C0D4AEEAE2AA8AF34486CED02F3EF468FBC8B40FF56E2E255EFA6D31D989F73D85FCD74B6D0EB95A2B55309AED92D4A311F6980E9C91B015047EBB45413794298CCC3910055BC771FBAABFAD11BCE3CC524D0A5F3249398AA0FE139D398E43F519447BF42DF7A9CE34E24DB290159017149DE05556D662548C90131308BDE61B2E14F49C9A8F79100FB44B4C182C03EC9A4443BFDB3DED409B62963A711FED8191CE26D6F17B69889F10EC49632FAD9816AC75BB8C96895F6ADE175A7507D38C10CB37A72504B89C047F63706F6B4DA04CFA805D291F84DA600FB94D4950EEC077150788177CFC18874F528C8962A2BA12336ECFCBA5BFDDAE0D8CDDDBDC90542F5334FC9B5754BCE7F55DEE1249D8695E6C07DE58F2AFED87C50122F0C40BD5BC0A2C47FDD346A5E7E883A801CED84B9D8EF76DAA259785C8039FAC1B82F9E25432BFDB429026E93D814984C74568A029FF0128CF9E5ACBB293580F8DA8E9854022103E5084F51896A0A09F4FC1517CD2274DCCD9E2CE15AF82A4EB6557A684C3152F0716 +ct = 933845B3895D972351175320E0336AAB1905625CF839D7B9971F7A0674987B7CB21C15B96CF52786FAEC0E0AC339DBD1AE5FE35135AB6F89A3E38578D2C4E1E98F77B7C7DBCC9B18C95A1CEE0C7C75E1FD04F57E4A36103700A1309BBA1A07E44DF5A225FCD14F928436D20481AAAA04518AE81F0BD49D80BDB9614E130E5F2204236FA57B0C67353076F9A995A14F46DC8EE1BD5BCF1FDA7EA17231BEB912AF87760AE67F5636DE6DA9579DA5893E8A5C431AB8A392CF7DB0B9D735D4DF7D696F5B5B80BBDF2638B7234553A316F7A8160E347C04F570F628AF6054C15D3F3FF233FE8D85E4EA77E4997EB5613B8E5E8A3D40641A70168E9A0F2B689B6979AE493D41500CB42574390951B5B09E70C8F5FA194EE2A9ADFBB828EFAD08E074E28C802DE84C3A0F082408AD8EF63B142C32F6023ADBD52C93A15E340B14B63E03494AF87347006377EBDEDA9D4DE0C28CC826B400F85D826EF20684F3D63069D8C5271703DAC9E3C6DF7BC306B21ACFEEFBF1053564CD784572C1F786CEC82FA87DBFBF527BD0DE0E19EFE281B67DFF1EE2F69075D7E3EDF8E11BB127D1BFDFE6EA2B9510C3666AD966284DAF66E5B70B1DDBCA0C86C4FDE98BC8772447AABF1BF7EC9024FE03C59F0C524FF0DDE338B22B0E6E75FA59D3557C10DC799DDEEB80C85D7E2557345E743B56C6C220B228E34453E7C2A23E6D282B81703E02A28A884EB46346A5D8DF4EE150734A4BDFCFB46A9064B11493FC5EB0F7041E6C7B70ABDEED7FCA389C6742AA3DDFFA592B37E3C6A8744F4DE930C4736872679B20B71B9CA1D02F14DA8E24256161AC2D621A43722D6B88 +ss = 228AF7F8303C8994F39B92F62BF8EAAA5D34BE0459D946ACB21CFABFC0714BE5 + +count = 37 +seed = D882BA69AC8BBC88715F1C6387531F53273A5DAB87E66FAA8221A7F628D2BDEEE1CBC59C0E08D0ADD84520A3A70C1389 +pk = 31E409C9E8C5498B444F62C15A9DE8E7A82B0743AF9698E4A68B898FE78F583CAAFE652ACB7FF00B1D39F96580090C34D00544A10AF9EEDB5A3B22B6D3D9598162BFBFD42883B9189BA8AA699BBE41B1F7772C2C202C6C15429DC293D4626F50F4A98CF475BF03B34DCF2E2010F5AE7AB821B0D4BAF7D61A668FD4AFCF43AA445AA938179F451D974E131AF3A73AA1A24987292DC1629B2F69713BE18F10FED32EC8D133B254A65F0A6111A36ABA564B29908CE3AE285E111AFAAD5A819A458101199ACF475A87DCBA7A54AF10B7880468468678F9A8BC2BD73F128EB1C0BDB74872AF2F84A06CAF06660E1ED89A36026656C3A5AAD6D6D1E7ACD2AA6F78C9D32C5324A86AC18ED7236660D9A58BD67229507A74EACAF1C1F9148199804A39EFCB854073560ED9CFF3CCF02A1E53457FD3BD342FF27C8D7B446E222AC8C564684BBB471972A0FAD9A46F618B19E3D7638095E158349C1AFB5F032A0A1AF68003A644D39FA6B2215B0C0F6167E986495D3E8A6882F876BB0007229275118DCC78346A347B046F2EBAE7F84B3B6BCECED6457A1589B0644B5FB213B809542290A5C619264B9C4BEDAB132BEA56B6790274A2D57C0CA001CC99A4D590DD7DABD64179E8AA04471AE85086E964A35175F8E96991A171561E0E19F45187D7FD24DC443B4D40D6A11F918B3054D566971EFB038916E621771D2DA01CD8B76C2213D3ACC71E6AE89F8C7BDDBE3FA064660E12289EC9DAE88586147FA979F7A19D4461895D060A8F68CC8FD2F64C9F63EDD1BD505AF39441 +sk = A1B52D871612A1C611AE0944F9E71858F35D3BD14F20E96A931720668BDF0A6B1F135CF64B6403E103AFAE34DA038613E2853BBFC36BAAFA3C6A95347193F37C130BCFE031E637AE84406A08F8C6F70131E409C9E8C5498B444F62C15A9DE8E7A82B0743AF9698E4A68B898FE78F583CAAFE652ACB7FF00B1D39F96580090C34D00544A10AF9EEDB5A3B22B6D3D9598162BFBFD42883B9189BA8AA699BBE41B1F7772C2C202C6C15429DC293D4626F50F4A98CF475BF03B34DCF2E2010F5AE7AB821B0D4BAF7D61A668FD4AFCF43AA445AA938179F451D974E131AF3A73AA1A24987292DC1629B2F69713BE18F10FED32EC8D133B254A65F0A6111A36ABA564B29908CE3AE285E111AFAAD5A819A458101199ACF475A87DCBA7A54AF10B7880468468678F9A8BC2BD73F128EB1C0BDB74872AF2F84A06CAF06660E1ED89A36026656C3A5AAD6D6D1E7ACD2AA6F78C9D32C5324A86AC18ED7236660D9A58BD67229507A74EACAF1C1F9148199804A39EFCB854073560ED9CFF3CCF02A1E53457FD3BD342FF27C8D7B446E222AC8C564684BBB471972A0FAD9A46F618B19E3D7638095E158349C1AFB5F032A0A1AF68003A644D39FA6B2215B0C0F6167E986495D3E8A6882F876BB0007229275118DCC78346A347B046F2EBAE7F84B3B6BCECED6457A1589B0644B5FB213B809542290A5C619264B9C4BEDAB132BEA56B6790274A2D57C0CA001CC99A4D590DD7DABD64179E8AA04471AE85086E964A35175F8E96991A171561E0E19F45187D7FD24DC443B4D40D6A11F918B3054D566971EFB038916E621771D2DA01CD8B76C2213D3ACC71E6AE89F8C7BDDBE3FA064660E12289EC9DAE88586147FA979F7A19D4461895D060A8F68CC8FD2F64C9F63EDD1BD505AF39441 +ct = 1A47DDAA33F3440CB2130E3D251C7CC30AFBD46CBC8D7E68E1BC8F3E6ACFCCA0B10B6C06DD7F512D34A305BF0BBC0004708FE8C4133C7AC5C61313A2703E970A94E3C0E15A3C1C1418C83DC16A872ED31238B0E1FA45CCDD908521A704117E61E7765E9044790A82E63BE813DBC1E14765D2D1072EBEE2C6C658AFDB095FFD8F2AD522C5C2148A8BF42B128C576BE5CA03F6555AF46F6F2EEE72492E65A834A21540F18DC8CBA627E10B4C736FEC96D0A25F9B6B88DB16C70810D30F7E07013AC8B178D8ECA88C13BC5BFCDE6835A39747C66A04CE84ED6781BB5647DA83B88E2DBA9EDECFF1D2FE30B85DEA6A0147E96EDCF574D7EFDA592902775F416EA9C02DAC37FCE2D7606D8D5C0AA20E462FF92E44B251B5B6ACEF226576DE1C6FDF9FEF16C307206D49FBA2D5B7F105F73A82357DE9F36446266D5DE11A8DE2EC1700D3A1E58750413F931C3391D3984961717E7546A04AFA18453E774F8BC21A911BD37F8EF3725CB35109B2C8A9BA0FBCFC42B4B589D3460669BB4E74226A93E34B979F9E40B5EDEAB0F688D4BF98E357346F48798CFC316B356550327DA066459A740E34995CA439F3BD97109E545BDDC951ACAC431A170BA557AC4D930B4C45CEADE21C2BFA6A8A0515E8D99CE166FE2851C901D54B524A4967546A2D3459230B78E1979D5255150719D7EB6D0D517C80089F69C7F0C3FFE322B208960D56AE4D3DEC2A3BB4469BFF698E01CFE9D8AF0B4B43C8D1A2D5A801EB4F3BA6F105895C306E71F73C06B3CA952C866D9480C6C4429177386B1DE8C630E7FA395E1AD407E0EB7A089E6EA74D4209C193BF4C67367A97137C +ss = 1A8218B58D3BE190E1050D633BB557DCD7C0C697BADF63E85B1D9355818DC3E7 + +count = 38 +seed = 6C3AFF39F5D097096D882F24717718C8A702382DC4AAFFD7629763FDA73C163CF084807BBB0C9F600CD31A7135F48AEC +pk = 6DDDE835276822FDBD716BB7D7E873907629B3204EE71D97422265F89643E113C8C3E2AEABD36C92CADAF72FA3EF06627A038C10F008E75E1DD399514493ACAC5D603F1961DA64A529DD27506F8DFA5ADCF3C9564A7986D48A609A9AAF66CCF61A07940845A26F6E3942E252BBF5CC435481C2C330DC654619A7E43CA1CB03DDCD6659DC2BDC11D03F924443B689CED46174E43E2BF4B2F6EBA0B197918EE81B30ECB26AC536988F59DCBFFF94804C64F91EA6FE96344F9AE86F955C80F76C7BC3AF45BE9A36C3D5C4B489B44412011251BD1E9BC382D7E4A9E3547301ECF530F1CEE2C8302E29AD551363ED8B267F1150EFC056831BD7F85D64E1C9E1B2A114FAB4301B725965FB2660C030A8D5694D5C74279EB7D9FE52B014AC00664ED8B469C03A4C7EA384A319BFB5A5690AE3423F9FD85E370D053D0699B3CA19388F8034C1BBDC975753BD78894D1D87C5201AFBE216CC19AB9E8F9A4C58569F1B86750DD115CCD3DA5A5D50318EC3EAEE5524F7AA62BDD7EEE714BCB4B08BB2D1FEF2904E9A974B00383BE2435E465779C5A372CDB280B2D2EB968F037F2B668ED61C6701461F2B9D0539892D8C53908E3B6AD1747DA642BA258C2C57DF23741AA576E79B385083048357238A7208CBE4D5DF641D27CDA94B82315629E769289C53DA9FD6EB1F6D8051FEAA62874B230748F2DF135D0891921D0A5E53625DA6B4AF155D16F50A1E285BBD6DA2A2C464FDEB38CB508BB06751EB49025A54A65C95605D2F2A1DAFE3A01805552C166044244527CAEF2700 +sk = 952B49C803D6D6FBA69F4375ADCE8594847A00BCAE2179DA49AF2AED0423250262D7033947AE42CA53522A65FBAFE18D3BC3E0CB66164E9A094FE4B44D8977EDC0D0914DABB32055DA762B4A61FCD0036DDDE835276822FDBD716BB7D7E873907629B3204EE71D97422265F89643E113C8C3E2AEABD36C92CADAF72FA3EF06627A038C10F008E75E1DD399514493ACAC5D603F1961DA64A529DD27506F8DFA5ADCF3C9564A7986D48A609A9AAF66CCF61A07940845A26F6E3942E252BBF5CC435481C2C330DC654619A7E43CA1CB03DDCD6659DC2BDC11D03F924443B689CED46174E43E2BF4B2F6EBA0B197918EE81B30ECB26AC536988F59DCBFFF94804C64F91EA6FE96344F9AE86F955C80F76C7BC3AF45BE9A36C3D5C4B489B44412011251BD1E9BC382D7E4A9E3547301ECF530F1CEE2C8302E29AD551363ED8B267F1150EFC056831BD7F85D64E1C9E1B2A114FAB4301B725965FB2660C030A8D5694D5C74279EB7D9FE52B014AC00664ED8B469C03A4C7EA384A319BFB5A5690AE3423F9FD85E370D053D0699B3CA19388F8034C1BBDC975753BD78894D1D87C5201AFBE216CC19AB9E8F9A4C58569F1B86750DD115CCD3DA5A5D50318EC3EAEE5524F7AA62BDD7EEE714BCB4B08BB2D1FEF2904E9A974B00383BE2435E465779C5A372CDB280B2D2EB968F037F2B668ED61C6701461F2B9D0539892D8C53908E3B6AD1747DA642BA258C2C57DF23741AA576E79B385083048357238A7208CBE4D5DF641D27CDA94B82315629E769289C53DA9FD6EB1F6D8051FEAA62874B230748F2DF135D0891921D0A5E53625DA6B4AF155D16F50A1E285BBD6DA2A2C464FDEB38CB508BB06751EB49025A54A65C95605D2F2A1DAFE3A01805552C166044244527CAEF2700 +ct = E3A3288EB87D35E2D2AFE7B07E9A3CB19B645EB294861D803AEA2A5AE22EA9D2EE7DDE6380D7FE23518489E15359DA83BCE140BF6DCE834E5090402E517B060C27E49EDCAF136C806A7E826DB4ACDDC2F47B741D8D5B290A0285A1E14626732AF568471357A06DE364CA5441B16B5C0490F2EEA978BD1F6E6BC88B9A7B18D641FBB6D9D186341A9DBE4EED9D032F842A10A21D1F728CB33D457226CCE290B02CC3247B1CB84D43738B1318072EF3CD62D2AA2C92E11B0131547DA2291FCB3AB2DD4D73783FB4967475853429D121984B0592E7411988DF2F7C4D27505B0351F5AE1977B2CAAACD9DF295217ECEF6CA1F2466117FD33960972CDBF4BAEB45DC76AD1C51923D0878EA20C5D137795B8625BA2D55F45D265B1C4C5D715E6CED7A5461537940ECC7E2DF29CB22C7D4E4404B8391AA0474A391270F47E168458CD23D5D6429F195EB470964D3E924EC3C4D6163E8B7B116467BDBE299385E0158A3E3985F6FA70B6C692662423E0CDA292277DCC0EEC33A47DF263BA248A81338A48DAE9432F9864C3EFCC416BC74FA9E593EC8D1415E8FF060A6359B2B9D7E4F0813ACA20578542187E3BEBEE761C6459CA683D44F9D594BCCB29F2AF9EC7B77667C5560EC9F02F7372B67DCD70D226C21AE8EDE0EFE2F4DD3B3E385A874D3DF556045EA2717AAC848E44632FB3E23F8F8E9E0DE553DEF87CB222069273C49BC8D8DA51AE6CAFBC9218DA3F344B3D7FF9EF1A3A6A6AE964B767CDA430331B3439150A8EB4F2FB00F19D95F649B8004CF9121EBC2ED6C634797A70F965CD390325AC94F7EA5B07EB8239F49D111C1512BA6117B475248 +ss = A100827B09A30655B6CA3B34578B3BAAEB6241D32F00C83FF0E72355C6B1D102 + +count = 39 +seed = CF520B92A2E3677AFD003EC1EC6EF136A709D78F828C9C0DD4946EFBD451C5FAABFC83CA66F9D3D17EE4220553B7A69F +pk = 0866E2C4F2177C57A4D7006FAFF66741CCB9DD736945118C1945C2E378A2F3F278BE1FAFBE7B56466097418E3DF75636734D11B616E8E2C2017BD1206A0B4E78A74D69A2CDD1BC4C77DC6E2A27A26440F4471446666FC7A74E7FC9B8883074480D76BEEB03BD12159D9239D16B9A5BF124B4A9C4280C0A92D6E76F241CC06D1A9792C22F8C2E05F32F27400E09872FE2E832A8162C38F4D1AF9D54F3FA6524D55F7BC7829DE339C814BB75145B726D2C35F38322FF31CAD0C670A74674573B28AAE9D66F8985A73BADFE6387AA66D85EFB26E89C38226052A7FBDEAFB8EC09B98403D47F128DBB12F8BAE542B9D3DAF531BFB8F9557B88B29C274A0C62B2174BE0E37DCCE2CA27C85C207FD100936AE75788D11EADEC364298002011696B86D0736F93087FE7AA8129EA236C7515639AF05A30730870E64E1CCF47394F67D81707AC3B3F115B59225277E96C3E431EC153F58B87D9E5DDDA2EB726C2593B64465E1254EA11DA9363B8BF7E2B0C54A87A18A332430BA9B2284EFAFBE4E0C431556295A7610FC7955758BEED7D0E7B2D7DA54E5D2BD3D3356B974EA879F55D0BD5C80D68C46030403F309B563A793F8D13DDBF18B1A2B1213D74142BCCA0B85238821F23A15087B5E4804DBFF4A143BE34824A53D90F1F41BCD2DC8DB2EB9D68B15CC6091DDCAC0C6074475B85C365485C6D9EAFA54C652C27F3B183392A04B58B625712716917DB39EC99C4B0E42C3DA428898143D77F8DCAB52E325D50AFAD310526D859950C4DD34564E1CF54FD10349D71C116 +sk = 3C815E57E9233E975FA1630208AAB206B71AE0DB37A7A8789AC683D9F9B2D29801C8E376FDB140EE343106C093AF7CB149B316BA79446CEB4E5E0CEDB9B164F9C6828BD9D5A20A8B9E96890A51D201030866E2C4F2177C57A4D7006FAFF66741CCB9DD736945118C1945C2E378A2F3F278BE1FAFBE7B56466097418E3DF75636734D11B616E8E2C2017BD1206A0B4E78A74D69A2CDD1BC4C77DC6E2A27A26440F4471446666FC7A74E7FC9B8883074480D76BEEB03BD12159D9239D16B9A5BF124B4A9C4280C0A92D6E76F241CC06D1A9792C22F8C2E05F32F27400E09872FE2E832A8162C38F4D1AF9D54F3FA6524D55F7BC7829DE339C814BB75145B726D2C35F38322FF31CAD0C670A74674573B28AAE9D66F8985A73BADFE6387AA66D85EFB26E89C38226052A7FBDEAFB8EC09B98403D47F128DBB12F8BAE542B9D3DAF531BFB8F9557B88B29C274A0C62B2174BE0E37DCCE2CA27C85C207FD100936AE75788D11EADEC364298002011696B86D0736F93087FE7AA8129EA236C7515639AF05A30730870E64E1CCF47394F67D81707AC3B3F115B59225277E96C3E431EC153F58B87D9E5DDDA2EB726C2593B64465E1254EA11DA9363B8BF7E2B0C54A87A18A332430BA9B2284EFAFBE4E0C431556295A7610FC7955758BEED7D0E7B2D7DA54E5D2BD3D3356B974EA879F55D0BD5C80D68C46030403F309B563A793F8D13DDBF18B1A2B1213D74142BCCA0B85238821F23A15087B5E4804DBFF4A143BE34824A53D90F1F41BCD2DC8DB2EB9D68B15CC6091DDCAC0C6074475B85C365485C6D9EAFA54C652C27F3B183392A04B58B625712716917DB39EC99C4B0E42C3DA428898143D77F8DCAB52E325D50AFAD310526D859950C4DD34564E1CF54FD10349D71C116 +ct = E9DFA56CC270457CF2F7ED5E7AF10452508DE49896D9F1EA100A7C229379981E3277C94AD61353DDFE6069561AF2BC221567A9E1D942A29E5BFED67D404FF86C43C0FE968936FE22F0E3D1C649E1E13FBD80477A06E49A7822AF7C5B582631FEDFE4D8877B0D57D88DFE3116F385A53EB21FC6E5461A293A1862F9E29B483810A944B36BABF802CA10EC9C7F2D84DC7560BCDE7F2450FFE578ECB612D981C8ED3064616FE780FEA54C66A035C3A8A8884BD3045779DD121C5EC3236BD9EADBF630B52A2816F0C2B8AC529719F30C3E0266AFA25C808774709648FF8C3C96C79141A00AD0F2D1E59EB5BD017F57C38D51A9CC2625A2BBBEDCA9B3ACD4B769745D42E30CA0085B0C188E75F2704538ABFE0C2FB432CD34FCA04918F7BE7087A965F8C2BAC71863C3B8D309A7976EB536768537331E67731F7292C146BEBF56DBAD97741985E9BA2094E0A6F3DB4AC4C0F0FFCEACBF988C3A7F28B24C9500B40CD7A93DC4F62399648AAB394605EEDCFAD71D962BBBC5CD024B087B090A7361F7C47E63986E850EC0A82CBF98D42903CC042A6FFD478D3A311FBEDD48C682E940C3462D3F1093850CCB5A29EFF147B1C7D606B5175014A113855356C86C7DB95961C6CB4A90551EABD077FD4AEE57220A5086D655F22B4920ACCE18A13C23ACC5450F8285D6C1C1F1BDEDD86D2879894AB746A5379CD7F9832EB57D448E721089A8314B026BD9CA7A0C2A7CC09BFDE6F976065DA0DFE82F8DD9BBC8212A1A33D0DD5DD802340F9394D12FA12048BFA8CEA6F51CDA067AB7641CEB470C96E7EB907FE5410DE038568F1F76311B3327B5FD2A61F2CE0F +ss = B002FB1959388037C5C6BD4836F6ECD0C8F1E458150E55F71598508493AD891B + +count = 40 +seed = 197E5D562DE7E01BED4FC597DB28DC6EFDF0179F3A5BDA5F94CAA39D67BAE730540534D59A7A06C8448F628DA8B7859F +pk = 361A539EDC2374CC6DEFCA9A883A116A6222632F4F2014E49E870F9EBCDC72288BAE0CD499BBBE728683C90CCEDFB8F8E27033522224BFB652EDCBA2ECCC55E4267816366F35A105660C8995301470980CB8623F513BBAE758FE234B002A9D2034EE92ED0E8158D47F9E27047F4A81BB0A75BB1F60097167220F19C701469DC4E46F908AA1C0911775CE5DAA2F12674B999F829C6EEDD740D8AD931B52740F6AF2343257294653FE58C0AB188974FCB0AFC7808CAC993A7ED1568D4B6B1D4F2BB1427E398877AF974E858CB7955E4DB3FCF6F401AF6C99A042B6ACB6208B747F86ADB892708AF5E5E4131F72073AC8683DD1647BC4C0CB0A2B607E30C72A4898D318DF3ADA358B4D265C35B7F2E09B338D4AF388BEABE49FF325F7CBF0B2956B8F4F300D71C7D5287A84A84C432D5FED588F7069BDCB53215F5DCEE1F23DD86A00B8D194EE69F7F371FAEF7BEBDF9C1D30397F420019E803C7A2F08DD794EB454B898AC7E574F028DEF70979F59E7FB1B7D8F75FBC996855ECFD8EFDC0581463074760B789A2309738317D49B7000D6D7A1F651BA4FAB57AEE170FAE4145C76000E9CFCD96A99F1318AD91EF091A22265E797388620040D3EFAD0C3B671F43DAAC889E78CDF60E9D0AA539F5B5D4014C1BCB0AA56C07FA8C4C15769E023EC63460917073EC6FBAE1919CE449323CB2037EBE04CCA9BA1EC0C1FDC8E075D833D047884D24F41EA3A663332942D07A568A1D3CC32C35BA2AAF6465366BC3CC5D756F16B76C4A3105C5B3073D441A8222532D91F94D +sk = 588760826DCFBD36D9ABE6AE44A669BB3EBBA6A218EAB69E30F18A3BD536576E0E860576285483BB5FD36E2F944D32C4317BEBC1E441470C1372046A790D79D4F817C85D204EE860346635D4A8393902361A539EDC2374CC6DEFCA9A883A116A6222632F4F2014E49E870F9EBCDC72288BAE0CD499BBBE728683C90CCEDFB8F8E27033522224BFB652EDCBA2ECCC55E4267816366F35A105660C8995301470980CB8623F513BBAE758FE234B002A9D2034EE92ED0E8158D47F9E27047F4A81BB0A75BB1F60097167220F19C701469DC4E46F908AA1C0911775CE5DAA2F12674B999F829C6EEDD740D8AD931B52740F6AF2343257294653FE58C0AB188974FCB0AFC7808CAC993A7ED1568D4B6B1D4F2BB1427E398877AF974E858CB7955E4DB3FCF6F401AF6C99A042B6ACB6208B747F86ADB892708AF5E5E4131F72073AC8683DD1647BC4C0CB0A2B607E30C72A4898D318DF3ADA358B4D265C35B7F2E09B338D4AF388BEABE49FF325F7CBF0B2956B8F4F300D71C7D5287A84A84C432D5FED588F7069BDCB53215F5DCEE1F23DD86A00B8D194EE69F7F371FAEF7BEBDF9C1D30397F420019E803C7A2F08DD794EB454B898AC7E574F028DEF70979F59E7FB1B7D8F75FBC996855ECFD8EFDC0581463074760B789A2309738317D49B7000D6D7A1F651BA4FAB57AEE170FAE4145C76000E9CFCD96A99F1318AD91EF091A22265E797388620040D3EFAD0C3B671F43DAAC889E78CDF60E9D0AA539F5B5D4014C1BCB0AA56C07FA8C4C15769E023EC63460917073EC6FBAE1919CE449323CB2037EBE04CCA9BA1EC0C1FDC8E075D833D047884D24F41EA3A663332942D07A568A1D3CC32C35BA2AAF6465366BC3CC5D756F16B76C4A3105C5B3073D441A8222532D91F94D +ct = 50549477D288277D282C8F47709358B7D76122459B5ED4269BA853D53048B56B93707F5AFEEE4EE3EE4735BB1BF741BC985D0F665281FC470631BAC74049F2C3743550259865184A4767A87FDED82A76A7D8358A5893A2247CD0AB5256565ACB85E2504E8844B4EC6AE7B20B1838C7F46294783ACCA2E02B3022919A86E5996D82A0543CEC76344F7091E1B1B9C8B03E436589EC342031E2D3CFCDE63EBE5D41E6DDC6300C57CD65DF2048CC65AFE8491F68F04F427FD6673B206025B38166BFFBA84DD3DCB077BC8C0195B3A74EB7279280289FF960A547AD3015013151B27BA1233355EEF8E3CE9183D2452F0EC3FCA583865EBDC462C88383E9626FD5E24EEE1A9BBBD8C00A990F56F1EEDFFAFB0ABE8345D5302F9C4B323B6D7FEC16F8293A3CC8B3E01F432C10D8F6B1FDA3B309760A05D26C37658DB8BA2712BDFE8E328479CB4D47650F8C43A5473AA08AD85EDA6D72D8635F0374B515F7DE6856ABE4B9FF8147E8C8602ABA9AC578D8CB6ACA08E6BC62EE8A646A7D54643297835E51958EEFF6E9B570BBE575320FC78592D3023F34CCE5DE7DE4647032296F37051B576D01B24D53C58D7D202DAB3CAA5E928A64192779A34A5087966EEC1C67038DA0E09D700BAECB05188832EB9D5BA20FE65BC94AE0591AB7A24ACE7A7EC36D862DEDAE66F82B22EB39010EF67AD29BA871B889314550069C502CC868193BD823B7541987A6C15DFC053DFB59FD12FB32F92FCA748F5AF0361AC41ACBA221E2B938EBA80C57E711CE3954EEC54E915AD4C3AC443C0BCCBABB0E55B112A69044029E54BA8AE899E2ECA2924FC222ED62394CE51038 +ss = E168D04F9EF20435AAEEB03FA2A556CD628F309F512994AC8D45C5BD9A4C7CEB + +count = 41 +seed = F170583CB451D8A45D105457C02C01A33A40350616ED8515BD49067142F61EFB00F07857E4FFF3FE11E7164C648C76ED +pk = A0CDFA83F19BD1932E2DC1341227BA516B6955E12980D01BDD34EA4AE2FD8EB38F79068BAE6129B677426996AFEB165AA5218501774F11B54A6072CED608FA2B6F8F1CDDB4AE3BE4992383F0847735093B16E6DD2945F68F26F6B957E545B0E46BB3B78FF9A044C2956A3F36A169F071EA208AA5B59049EDE86FAB2BF96B750AF08B68EAC5EAF95FAFED36A728DB68CA29E458F9DB4D41EB6862DF2AF4A86C47BB65521DE99CAEA6DA371E304C3D5608DB6DED47E6FAFAB2C04EA4400E213392A0A1A492480450093856F298291B6305495F9E0CA01503086ECEDCA6F6CE04101CDDF1DEEF31873D63AE6C6618335FF90DBAD5ED09A2412390CAA29EE1A4572D6398044FB33D6256C0A06A97C6A4C598E60A26CFDF7897BA163B1B82D0EBAB25DA84FC57447C3FB36D83B25C08A019615A01ACF3DBB5D1F99EDCDBDFFB6F077B5D704BF77089B3E6941C3F49C642413A34F4A6AEE0445C6CC9C47EFC71B30BC44E131F2BE95C0E17F80C1B27F999BB393302E4210C66966920B1C48A36CC48F70E1A3DA3B6CC69330750BCBC44A95F611262A1BD5E9991E175EF9164ED360451E565B02818DCA7BEBFA237E3370D602C2C9E5CB58EA9A21C2C7C94DB68F18C2AEEB7CE7E6E3A91B68BFFA3FF3C07F42E96BEF6BF7724BC626A3E86F67D85601BD402FB7AABA039A43ACA3725A9E9CDB41C5420B15699DFD438E1A36D0E60751DAAA54879109EE4AE7A67051E194BB8ED6D0620614FCB12B950E1D5AE8CD308FD5625359A418D971AA44CA303BEEDD4E6363C0345 +sk = 47550E9EDACB6DDCE3D9AB81F6B61080DD4F2693854ACB05E0CCC7A4FB6390FBF89D7D99D5C3E0D10D6EF9AF054D842375F695ABB28E3B8EB495100F04306E92641960502A4293989699C6905C9DB300A0CDFA83F19BD1932E2DC1341227BA516B6955E12980D01BDD34EA4AE2FD8EB38F79068BAE6129B677426996AFEB165AA5218501774F11B54A6072CED608FA2B6F8F1CDDB4AE3BE4992383F0847735093B16E6DD2945F68F26F6B957E545B0E46BB3B78FF9A044C2956A3F36A169F071EA208AA5B59049EDE86FAB2BF96B750AF08B68EAC5EAF95FAFED36A728DB68CA29E458F9DB4D41EB6862DF2AF4A86C47BB65521DE99CAEA6DA371E304C3D5608DB6DED47E6FAFAB2C04EA4400E213392A0A1A492480450093856F298291B6305495F9E0CA01503086ECEDCA6F6CE04101CDDF1DEEF31873D63AE6C6618335FF90DBAD5ED09A2412390CAA29EE1A4572D6398044FB33D6256C0A06A97C6A4C598E60A26CFDF7897BA163B1B82D0EBAB25DA84FC57447C3FB36D83B25C08A019615A01ACF3DBB5D1F99EDCDBDFFB6F077B5D704BF77089B3E6941C3F49C642413A34F4A6AEE0445C6CC9C47EFC71B30BC44E131F2BE95C0E17F80C1B27F999BB393302E4210C66966920B1C48A36CC48F70E1A3DA3B6CC69330750BCBC44A95F611262A1BD5E9991E175EF9164ED360451E565B02818DCA7BEBFA237E3370D602C2C9E5CB58EA9A21C2C7C94DB68F18C2AEEB7CE7E6E3A91B68BFFA3FF3C07F42E96BEF6BF7724BC626A3E86F67D85601BD402FB7AABA039A43ACA3725A9E9CDB41C5420B15699DFD438E1A36D0E60751DAAA54879109EE4AE7A67051E194BB8ED6D0620614FCB12B950E1D5AE8CD308FD5625359A418D971AA44CA303BEEDD4E6363C0345 +ct = 5BBEFC27BFD5E40EFE5F18A3E7F3F11DE0FC4FE94F3EF14405D25446013117238302B48C67F29E64133A9CD3C07B6266143EB5554B3BC39E6624294D68D73138D780D4D3360E4944D1979F6A291D1E36292EA1F4D1B2297CBD0AB22E3D36FB1E024E0195268BB5A35080CE621F9A6070B2B9A2461605CA9B5CE51BB2256622EB45D19DB58EC98EF5334E9A3B5ECBC5A5CEF9B995066C1C882764213215097B8EB9171E9B931F86F93ED530897A94C97261E95A8FBFD814C30D3402085E9727CF7C7E5326A7D1F8060EAC883AE57F0DBD87566B20AF69D98A233C0024C8FF93E1D3A828D7CE2CD9BF3A17CC4E37FFDE2831D3BA528A3873E0327455C534DD22A38BD4A7ACD2C4F8D8A642B0E08AB14EBA438207B5C8FB14B15507F5096BF98FB36EC328DFD4D4C547AF658BF62A1C037ED8965470BD85AB9DA01CF3103D0D772C4F0634423A25F42AE0F7E108C768D544D9879807D6165B8885828E493035C0811D750F2A44BC495EB9F48144A75216D82473917B77952C0FBE49A329FCE9BB6AA908593CA86EDE3A33291D237F5B6BC575C07DB7880B32386E9AF1EA7B752B64ED89A8D2822C5DF191AEF884C16B758A9200F68E0E700E99076AAECCA4B7E7D402B2E14AA68BBD6570ABEF79440546F71BF44442500F7EA3A9956743159A904F96A423BDB5B60C9C388E310B04DF6B9E5B9F73B64ECE5DE8A0EDEA3895DA6EFA5A6CF6B6B93AFAFB6591CB33930925A3007586C3DC30779C3C88F37A16F0E036FA83E010E40BF289F2F5D8A7CEDC1491BA6F3F63B312688E041BD4E8424A27CBD70074702F7587279BB69D849FFBF30EDB422786 +ss = 42C434E1950DD73BC7D791973F82DB4BCD84EC988A8FA3C95737BA9B5DC5A597 + +count = 42 +seed = 44A6774B2CAC02DFF210FF861A090561A453DB311F47B6FEDB81811872D5D9489F5FC4103010139AE53FCAED209DC9BE +pk = C97BB99F73700965669142B2D9869EF77A6FD6BBF0EF059F983D6A6C2E3B9D72599E3CF5097193F3B8A978108A12DC8E865FE6CDB28D9376D1456BAD79530654BBF5168A29C0BDB79E031BA93107956970F3223E74490FCE9A41F806C6595F84C7CC415BD39B3AF0C0AAD9ECCABAC292AAD9E0B8875A41BA4A961567FF3953E4B9C1F35E016106A8E91BBDA09EFCAFDDA26EADA1C91ABA164C5373DE13624376E9EC822B9144E7C02E2C192BFF2F3A2F96EE80D90620B93FA793F2346243B4FA4DDF581B820ED6C6677E7B30EBFB15459BB6C426491E54ADE77413F1C83A50493665264AE402B649AB2DCC784A3906758EF6A2133360595AC27247FD4F5F4E6845ED3377DC7924E55E993FEC05DD1C54EA4EE0F87224A8EB3D6F6139A43A6CE64E437AE0EE23D46D0B37A350B4CE81F0CF6D2A05988E412914F839CF2BD3962DDCF0B26DA9809918989154C5510DB2886C06C50A0EA8208BB07C3212DA3B9A2E2ED82D882E515B378A5D24F36E17FE24C1DC1EB2739BA03AC40DC5BAC72D8CD147EF99C74F460FE4B959A3E8566909CC20E198C74D94F4FD0C707E17A7E46B9263EC9A8BCECBD9E12726C472AE52C818F1200195800B4D5E8CFE01702DD0DDD163E4A591DDE787B1726D5690D5C1220F284130760B1F3E2E1C72C5E8363422C24FE60A150D9A92FF9A43F5585349363F1891DECBF9501B96927DF563928FB82DB58ABF9146400F93F16066553C03D41A35C0019E77B5090BB859CC4E0E37F6476AFC5A80C808FBFFB2DF27EA23C117914A120630 +sk = 610AFB64BE8CC1DF288CFB016EE2F44C6C07113DE7F6FEE071FE0C3FE31C6215CD292E4C5F9E1A55E0489BCEFFB204D672A6215F4F3980A646D9F880817C52DDE963EB230D9043216BFC31722EB2A203C97BB99F73700965669142B2D9869EF77A6FD6BBF0EF059F983D6A6C2E3B9D72599E3CF5097193F3B8A978108A12DC8E865FE6CDB28D9376D1456BAD79530654BBF5168A29C0BDB79E031BA93107956970F3223E74490FCE9A41F806C6595F84C7CC415BD39B3AF0C0AAD9ECCABAC292AAD9E0B8875A41BA4A961567FF3953E4B9C1F35E016106A8E91BBDA09EFCAFDDA26EADA1C91ABA164C5373DE13624376E9EC822B9144E7C02E2C192BFF2F3A2F96EE80D90620B93FA793F2346243B4FA4DDF581B820ED6C6677E7B30EBFB15459BB6C426491E54ADE77413F1C83A50493665264AE402B649AB2DCC784A3906758EF6A2133360595AC27247FD4F5F4E6845ED3377DC7924E55E993FEC05DD1C54EA4EE0F87224A8EB3D6F6139A43A6CE64E437AE0EE23D46D0B37A350B4CE81F0CF6D2A05988E412914F839CF2BD3962DDCF0B26DA9809918989154C5510DB2886C06C50A0EA8208BB07C3212DA3B9A2E2ED82D882E515B378A5D24F36E17FE24C1DC1EB2739BA03AC40DC5BAC72D8CD147EF99C74F460FE4B959A3E8566909CC20E198C74D94F4FD0C707E17A7E46B9263EC9A8BCECBD9E12726C472AE52C818F1200195800B4D5E8CFE01702DD0DDD163E4A591DDE787B1726D5690D5C1220F284130760B1F3E2E1C72C5E8363422C24FE60A150D9A92FF9A43F5585349363F1891DECBF9501B96927DF563928FB82DB58ABF9146400F93F16066553C03D41A35C0019E77B5090BB859CC4E0E37F6476AFC5A80C808FBFFB2DF27EA23C117914A120630 +ct = F5DBA183B32B7F8344BBC38009F18CE09569CB9822F64F45F94C1B5B98C497CFDBB11DACF23C9FD34570F6FAE41BB97C123054629094E11BD0B4E449E4DFA5AB477D7E8AEA7D3378F366A7012F8FCBF9225193ADB1F76D833301F8920832EF3AB924DEF54B2E546A95C9B840A7B08866FB7D9D9E3BA028F696B4D68A40C2C878EDD5202C7EB84A023C390EE977A8B085C6B87550C4A5078CC6129672C069BE25BF026FF21F8B529BC31C015256486E5A1311CE3BFA61809584C908291E8D0995709A2529D9DBB5A0064B2EC3F3BF7A19F805450757A0C9086BF00E5EA686404A5540EE873F27C606134EACA4ABF08890618FCD4F876E09250EBF4BBD403AAFFFB208DC8430590ECEB93ACB741F4FFD772186797F0BC14A3210514A5E3343909717A393F27513BE6BDE0E1E46B039C2D840FF74F4BA0248157A64D50CEF75AE56B0D0992E99B74C76B6B3F15972A86B2F35A63938996DBE574038468CF5B1DE671A4509C14A0DE091876E8FFC5D8C1DA7BB73126F72A6AB228692F2A9F17E6115943D17C28115346495CCA93797E64A605CD5AD884C9418363FBF175404586E47E148A4484C949715977E95D8E3CA65D27C011546A9774F2ECBB949D81BDE97FD85681A59C3CF614B2876FB78F10BFBF63F8DA8409A58E71A7ADD697E11E36E31649ED6C3B9BD50E71D7B0E40EB85670B7D4833FC87F2CAAD1AE8C6A3A001DF6BC91A4A12A13393A687C72540FF9D2D7B39DA1296611CBA9F93E1BF249BA0E8378C90C689E6142C4EF2E51601A03A51741658C4281070C72967316465E95EE5F39829B33FE13F98C5BE234AE8738D9943A4C5AF09 +ss = 5C9EF53393459AD3D3EE31C82CFF7AC2B7C48F1BB01F6874A461D2B94D6FD5AD + +count = 43 +seed = 49E1855588B6235DF2A400C4A70AEDF8AB17B6E5E2891AA745F132FA2E7AB0C8117C1DF37C39F5D57624EB77C2B4A091 +pk = 7FE3EA04D3154198AF4894BEBD6DDE1586026718C1F911A3F27572D4BEEF615E3214E056A9CAE83CBEA3505737F75B03541F272977F6E46315A482D5DB35732E6539D25CCE19B07BB4BA9208DC4ED794217585D45C70FB8D90E7D81A5335E3ED081BE00C920CEC81F371042574B1C7A6F820C21C7EDDE3FEE35CDB01F63D58C01D90974BC1FD195DB1BF4057702EDF3540640CA7305AB2B2B52F0AF6491E2E284645BA587EC36B7ED1F18FC24A877CD02D18D853B0271EEC1690946C6992B992A93D27DA45FCAD66A0526669399675D420C6FE22292648AE0F58E4BC1EBDA331C1F706B57CFEDFB4A9B9DC7A27AD5CEBF68BEE7313DD571227BB1A730CF628C4BA4C7CB9CD988351AF09C355C0FFC75623D6FF3E43518FEDDB4C862FA0E72A22BAAD7209656AB64DF3B4055D626443783A9C20E7C71DF13810F39034977B1862E28F4F5D33B35AE59734317DC0474AD0FE67C72310BCD943F319A18D0FC8C044B4D04EE7CC3CA72684C239B774F12D79614C0464E573A613F1685721599EC2D3377BA1341FCCB2382AF11804D3D5E675F47C4F55344E1BFAFDE73F098322DC220666D7828131032166ED7BCB3C077CBBFA391D7AF1E740F328CAFEA09818FF6805FA521DEE4157279118143BB4F58B1EB0D0C9F52B04364CA73D2BF536C97A12A9267B6388FD92B198633394B05B5164AA0B87A7E562DEB10464CCFE4C91F7381F0BA40F7AAD0FBD5E8BBE7753904A62A6B8F9FD0CCB373F6FACBF932BC121BEE3EA5D015E957768E55482F7EA1004D7987FDB56 +sk = E1953800ACAA85AC02A906C72CB8E8D704E8D27820345F88F71E89C1F549AFCC8C64C049C6DFC0F1476CFFD520B055756162F7EC94243DE6B14AC0B9E5FB366C2EBA73D4AED17740C1DC2B67CA15DD017FE3EA04D3154198AF4894BEBD6DDE1586026718C1F911A3F27572D4BEEF615E3214E056A9CAE83CBEA3505737F75B03541F272977F6E46315A482D5DB35732E6539D25CCE19B07BB4BA9208DC4ED794217585D45C70FB8D90E7D81A5335E3ED081BE00C920CEC81F371042574B1C7A6F820C21C7EDDE3FEE35CDB01F63D58C01D90974BC1FD195DB1BF4057702EDF3540640CA7305AB2B2B52F0AF6491E2E284645BA587EC36B7ED1F18FC24A877CD02D18D853B0271EEC1690946C6992B992A93D27DA45FCAD66A0526669399675D420C6FE22292648AE0F58E4BC1EBDA331C1F706B57CFEDFB4A9B9DC7A27AD5CEBF68BEE7313DD571227BB1A730CF628C4BA4C7CB9CD988351AF09C355C0FFC75623D6FF3E43518FEDDB4C862FA0E72A22BAAD7209656AB64DF3B4055D626443783A9C20E7C71DF13810F39034977B1862E28F4F5D33B35AE59734317DC0474AD0FE67C72310BCD943F319A18D0FC8C044B4D04EE7CC3CA72684C239B774F12D79614C0464E573A613F1685721599EC2D3377BA1341FCCB2382AF11804D3D5E675F47C4F55344E1BFAFDE73F098322DC220666D7828131032166ED7BCB3C077CBBFA391D7AF1E740F328CAFEA09818FF6805FA521DEE4157279118143BB4F58B1EB0D0C9F52B04364CA73D2BF536C97A12A9267B6388FD92B198633394B05B5164AA0B87A7E562DEB10464CCFE4C91F7381F0BA40F7AAD0FBD5E8BBE7753904A62A6B8F9FD0CCB373F6FACBF932BC121BEE3EA5D015E957768E55482F7EA1004D7987FDB56 +ct = EAAACB0AB4E3857866E803221174BED29EA687590386ABAE72543F7BAC8E07AB05423B65EF7EC650A8F5AAD8BE75EA1F877F54C300E02A0DAC010E245399F342AC772EC4F573168F3DB342ECF60DE56A694FA154AFDF2BE120AD4FE6C15C5DD8F587C0D5E7F3F540E744FA52BC79BF19F5EF4AFAE21962EA61D13BE03D6173D69A976037201635029840109C17E8FA6FF141123AA3C126EBB9ECDE0B81551E2BBFF2A722B27068F76A7FBA384135C4F2A16F0114615E73431257004368D0C7CC45F24846BA0FB1BFF267E2FCD65C13A5F328EF7DFB73AD4FF3B3808D2F3616418381417C03616871D2177D35E1E4E6287C80A5A2864D1BC32FBFBA1DC0C39D72E53631993653127D662FEC6A69B98C13D941F281EC353C464F48040918369D2B26980C195E0A7A076494A30E2F305BAE3073654467D49483051632BB6A17E552BDBCF63FCC753628AF1E53514A10933AF6E2528600471DB9DD6723DA0056865C23B8921E2EC1FB713BD7043C32B89D21CD3BBC3B80D22161789CA35494955E61AB0C9C1B170298E42A14A466A1047F858B044ECCF923BDAAAB48430A8C22EB5E6A38776BF03CB7B38599D517C8C6B8784628D036BACB2131E6CAC8420F10739594ED29020B78CD87D05542D6F4B2AFF0531C8E6FCD2E66606D18887E917EAF0614381DE956CF9D970E91B54FA410B31058C43A6A63DF00B17244046F648EAA70649FFB96D7828F847A22790EAADD479235A86C3613843F910E6444F864514CBFB5A194FBB141C5A442C31C0190A23C4B42EAC336591AEA6CDAB327459069CE42C77886EC40A037A0CE98D6BCF1144F090FCCCDC3 +ss = 7073D9867E71CF32C57CFF13577E31EE75EDC74D3B4CD56271266921D6074C23 + +count = 44 +seed = DF0E41D2F6F86C1F79D31FD5878E7AB434FC0AF3A0D5F47D2AB3FEF31A42BD949B0E3629DF9F575BEFBB62E829E51DAE +pk = EA179E39A1BAA9063BA77CCCF9FFAF9139E419362F818C173AC1911DD9EEFE0594406C0C30D0910AF8E87CD77872C7B7F8459F7CD5FB50CF0CB14AD97682F7BC9F81DB01588996E86D816F3143F10C05581394A88A33B8B00277D9552E4BFF58C76D15DEBB07E05C8C7FF6B51E266F144D34945CD87BEE2D80D3B75F7B965B5022D1D2F957CA93A44472E93DD3F542B1D0FED3D3B64E8AD75B3146A0F09195EA782FA7F82A6EF309E007980A6F68A96CDC9DD78BD836AC2AE63063064A36146841E5041B813AEEA8145CBB30BA9252EE0A94C4EBF34E94DC9D0CC407AA1F041E775C632E8C075DC8390FB83A4E431CEE59887866DD87B2DF3CCA8F4EC0344C8A8F288765516AF374A03C8C65F968E24BEEB3D043EBD50E103050CFCC355106BAE026C5BDA09C9D8292449F6C5CE060EB678B92B0E45D28177F60F3CA98665CF5C504EC0AA7D99A8E54ADD5BE8653F8892A582017A1A996A6DC40B16D98695DA8BDBFFB722D7632758C931DA06F420411B3DFAB16AF73BB1CB3EE6DBE838626330D5C69EA2A300C3D113764AF733094964C8DB9A070E9F2815D6C524D0ACC924559580F9FB59254EAC0D9BC4C33D52CB1840E9DA29B7A47D42111E5E2F42E09DCB9CBBAC6368C8F23607234E19F09F06E0205D5CDEF4EE9229D0F2338D64D65905DF7DE09686E7C4B7397C68A89F1F9BB1A4BC6DFFC05B5A11FAF6BB9EE47F2DBDDD75B9E3AB731098F6B9E8B30787693EA03B6FC69CCBEFC966B4A2ADC00AB93D810D1DF11B448CABC64052866567EA480024D3A +sk = C719F9B2D16399B7326CE4ECA30DABEFE8FDAAB18E9F6DF888B0A134EF355570E40771856EB77E4633504899FCB86C6A3D433D0B8D60E26F07BD61F1D4ED69BD43ECB0987E039EEFB08896A033E7C703EA179E39A1BAA9063BA77CCCF9FFAF9139E419362F818C173AC1911DD9EEFE0594406C0C30D0910AF8E87CD77872C7B7F8459F7CD5FB50CF0CB14AD97682F7BC9F81DB01588996E86D816F3143F10C05581394A88A33B8B00277D9552E4BFF58C76D15DEBB07E05C8C7FF6B51E266F144D34945CD87BEE2D80D3B75F7B965B5022D1D2F957CA93A44472E93DD3F542B1D0FED3D3B64E8AD75B3146A0F09195EA782FA7F82A6EF309E007980A6F68A96CDC9DD78BD836AC2AE63063064A36146841E5041B813AEEA8145CBB30BA9252EE0A94C4EBF34E94DC9D0CC407AA1F041E775C632E8C075DC8390FB83A4E431CEE59887866DD87B2DF3CCA8F4EC0344C8A8F288765516AF374A03C8C65F968E24BEEB3D043EBD50E103050CFCC355106BAE026C5BDA09C9D8292449F6C5CE060EB678B92B0E45D28177F60F3CA98665CF5C504EC0AA7D99A8E54ADD5BE8653F8892A582017A1A996A6DC40B16D98695DA8BDBFFB722D7632758C931DA06F420411B3DFAB16AF73BB1CB3EE6DBE838626330D5C69EA2A300C3D113764AF733094964C8DB9A070E9F2815D6C524D0ACC924559580F9FB59254EAC0D9BC4C33D52CB1840E9DA29B7A47D42111E5E2F42E09DCB9CBBAC6368C8F23607234E19F09F06E0205D5CDEF4EE9229D0F2338D64D65905DF7DE09686E7C4B7397C68A89F1F9BB1A4BC6DFFC05B5A11FAF6BB9EE47F2DBDDD75B9E3AB731098F6B9E8B30787693EA03B6FC69CCBEFC966B4A2ADC00AB93D810D1DF11B448CABC64052866567EA480024D3A +ct = E08C30A230761F7D5A0DB8BA11E6804BA59048565ACE3DE0910A7B85ACD41C3E915E73C841FA52C8957A8BD82A06576161D81D838B504C1A8D95641927A346A0D2FBE493686650EFC2065B8BFC71ED4D0E7DE066B804FC467A3F3F9E24598BE2CD520B9DAC1B1BB5A28D5D2A35F824F563ED31E4FB5754C6DF8C9E1D9CB5B363537BAE541BE3AA88079ADC9C2AD9F6BB83A05E0E769E17C674B7F640A96C4AC5FB6344BC235402512918252C6F262DE4FD978E61BC6A676E4E655364814933F15C004323DCF82AA080716F6B3F0ABF53CBB186B15338537DFC72DD578AFF245F2C6C97625596C6BCA51461D0DA7B0C494F63AAD043DE99B51745C98E0610ACDE3BBC09A4552ED9D4B404C5FCB1C27C1A7D2B58BC633531286D3AE6EB9BB968B3D3190E1A5B3287129C4ACB8CE6E55B394CA79465866BFCA12E41A34B273ABFFD822E6A49D3B68CC8A94142E25F514C7541DA6A66C761808200DE9634733C7AEEB5781401FFAD17A9ABB9C6B299950ED57D4572697FCAF33CFABBD7BB00E59E6FBE64AC7140AA7B7D42E19FDC95F4ED1CA1B35C76837163B536AD0C083983687836E70BFA0CACF73F5FCA7A34A51BCDB5E6ADDE9123372A501A0339D29F36E3CD4416C8DAD39606249C5819E6C846B9D4755D46A0DB425BEE19EDAA540FCC6B877E0CD91B47CF3546872C01565B9717AAAFFBAA3B42BAEC0A089BEF595C3D7090F0A0C61EBF2F6CC23F6D2205956FAB63AE05978600CBB74750A3413030AFD7B0082C27729A475A7EA91B5643B34BAC4BA22269638573A07371D1606D0143A030FCAC21D53655A4826A60274C1A3C2FD68D357F1C +ss = 91BE7DD57957734D1F99FBB3B8348466866D62661B3A5C635E6A0FE0B26CB238 + +count = 45 +seed = D3C9EBBA6EB03CCB5C9B9D2C8D7F0CFBBF50841E24396CDDF0E56525B38918C2FBE6C34CC1B93F7BCD4F4D5777E1A488 +pk = 6BB300D6E9C072566C0AF39CB74FDD5CA9CDCDC69D6354512657F7E4484A8C35889E2B3108B2663CA5104EDC036F842FA79D14D42CF28D6B28256F4273B87E5F0CFCC67E68315E1C0195DFBB4B3F2EA21E1D1E8A334DA3A9C29B022891373063FF2152ACE06248BFB3A234AFFDCD4B3019C8AB197416DA48BADBC69ACE9D53E1C5E7EB42C8DAC3D59EEE60155C47FD646CAEBB4B6AE1FF57EE67D03FBF783AC2F04CD56228DA900BD6A705E53FE62A50BE57B53F3CA4157FD5B2A612325D53EF93AC0101D35CED0581CE8C1A15D6898C3A3DB5061AAEE14A2CD70B37347EEDB96D070446809BF224C195E1A4CEB43AB31D508C38C3EB069B128D7550ECD5DCF682239B51CA5DF3DED7C1A86AFE0BBC7297CF85E39E9F6A0BE35FC58F92BD3DE7E215CB9B271FCC6796C838B6720465BA8EB91C7C9A9B403F5AC4AD9216672D0DD7A109717B2068F73BBC60EE03ED611AB70D9BB5B18DE3338D86896766F1C533C11456F872924C73D3AA6F3B457D0EEDF30A421E90A4C14CE6F8A26950C800763CE8C5C55055512B7D1D978E894B33689F624F9A50377C1079077501F96D11EF754981EEBDB5A8906EE44280881FDFEAE05CB815A2FB824BEAFF5138B357E167A98855DAF7D7A502E03809F0C460F3EF5B238021315AC83C7A12565C4CF4EBB2406EFF20199A600BF88900F87F9DE1129B2CF860EE61FC66AF23368CFB92495CD641D0D54E75A23EE8801A421C740A5C470688B930B641B1CB83310D5A1EFBE7A723E4A1E60B705FC7718A2691E248D486A5D166 +sk = E9ACBB774BE970206C3A738E243B420805A509FA59FA902044BE2F0D013650D2DED5EDAEC5DE3BF5B4D7C2F2E18E87F499C1968993EFF196753DB8045E2C8BA8EEB442F8E281548F83319144EFE741006BB300D6E9C072566C0AF39CB74FDD5CA9CDCDC69D6354512657F7E4484A8C35889E2B3108B2663CA5104EDC036F842FA79D14D42CF28D6B28256F4273B87E5F0CFCC67E68315E1C0195DFBB4B3F2EA21E1D1E8A334DA3A9C29B022891373063FF2152ACE06248BFB3A234AFFDCD4B3019C8AB197416DA48BADBC69ACE9D53E1C5E7EB42C8DAC3D59EEE60155C47FD646CAEBB4B6AE1FF57EE67D03FBF783AC2F04CD56228DA900BD6A705E53FE62A50BE57B53F3CA4157FD5B2A612325D53EF93AC0101D35CED0581CE8C1A15D6898C3A3DB5061AAEE14A2CD70B37347EEDB96D070446809BF224C195E1A4CEB43AB31D508C38C3EB069B128D7550ECD5DCF682239B51CA5DF3DED7C1A86AFE0BBC7297CF85E39E9F6A0BE35FC58F92BD3DE7E215CB9B271FCC6796C838B6720465BA8EB91C7C9A9B403F5AC4AD9216672D0DD7A109717B2068F73BBC60EE03ED611AB70D9BB5B18DE3338D86896766F1C533C11456F872924C73D3AA6F3B457D0EEDF30A421E90A4C14CE6F8A26950C800763CE8C5C55055512B7D1D978E894B33689F624F9A50377C1079077501F96D11EF754981EEBDB5A8906EE44280881FDFEAE05CB815A2FB824BEAFF5138B357E167A98855DAF7D7A502E03809F0C460F3EF5B238021315AC83C7A12565C4CF4EBB2406EFF20199A600BF88900F87F9DE1129B2CF860EE61FC66AF23368CFB92495CD641D0D54E75A23EE8801A421C740A5C470688B930B641B1CB83310D5A1EFBE7A723E4A1E60B705FC7718A2691E248D486A5D166 +ct = 86615B86948831B09097A88714B92B75A8AFBD103999729A83B22E751B688D1BE92ECC8CF46B790DF81806151B56EEE206B34960F724DAD2125DDB1CB092175C5288FC8AB57EB637452F3C34185EF3255C8756D1D7ACEC3E248953A96C10F56DCA76A20E218D135C51F596D9C435279BF09AE80C13BAC39B28F7DB7CD4705462CD4078FE4E7E46DFD453E5BF0AA5AB26FA2F782D72DB4E747438B79F54106B251088F90FF6D922CED54119269BF617C3681E94591CC34BDBA1598920A399B1B88458075D0FF01F31645914D81CCAD1E2B234A774196D642170AFBA66847D6D1C845B2CBF14A225578DEC68CCA768A68840A5FD5817CEF6D45BE19440AEF2423D7BE71DDD28AA2C88B2D49B8C0195FFF308B18EC9BEBA6745A42128940B1DC351B67F9CD9DD8342C2C758195F139026169BB8942DA5BEC12CB6923E36DDB4562128B2275366D32A6605E8A2C50830441712DDB4D62F0AEE08FEF5244F7F971737C87006E1C633ABB4EF5A1313B875676782FBE9D36AA7AE4D1713C76AF5533BD7B73B7639344AC0140F7E4B688D73F34BC0DA3463F8053AE67E6693C939BA9156B5BB930EA58D5354359EB00D46E2414ED9EE01121F8BB7E3E50206284FF964272AF885A0404FCEF9365B07E6A11D120E991B9C298362C93478151BF899DF0BD045BDFA5FD53CEDB6A8407CE974510EA64FA103063ED8EB40C277B4F909F022C9FD0BFF7FC1AD64DCD60248A701EF686659E1F9EB3828ED4E2BF7D4BEB8854B92AAAB941AFBB88AB1C0C9B91A32246F79E168E03091B3E69FA350CCC345ECC9B2CCF6819E8A2DDDE835C85EF6CBFC5F138E2FEE33 +ss = 7D632857976B5828CA4134D42DDD775C4050823D501713B7AB62413136C5C13E + +count = 46 +seed = 6B3996E8BC6F52879F2B7BE012C44AD555707CB7E5FD8ABB3457A298336D6FDC9EB7853008FF13201D5969A315C7E493 +pk = A615E593BE16AD92C8C000C56A7A09C5B793F477F26D379A3A2D3176AB97243738A80ECE4880500F37B067880903AAEB76D8A09B7B0C766F5D74F28F343A5EB0E605BD546FEAE1EE1DF9D5D30D507A8F53185A5A87698D9FD2F4802D8D293BF87F3FB09471BD5CE72612F712970ADB8F0087E06157C1A28B84AFB9A642D8DE08001F04777F5906920A54DB74672998321A1A9282371B13752B2919D62E90DF1E6E654786FA7E99DDB072AA574AFCFF8D4606977CE38F5C0A1AB1E04216F7667779A3E0E8AB3895C299E7CAD3B867A0BF90A447591C3E8EF5969B0A9974B2EFE21345EE07514A80EF4EDFF33E6397F19A09561D8F3D58B48FA555B7AE3F8F1EA2A728318ED4D20E2AFDFC202B8EE4F40EBBB76E8879B08D754B4EFA008A816BC07833BE03AE55136C4B5B04509A9056075490AFC3FA9A454E8340B86A65B1E96EA1A217D30788C1CEABF35889221058075FDD56E96181E850802AE946521750C0CF87076A074DA61816C4770E32F46A3A6C61EE551AFD294CCF17F3E9FD99D3E67BBCE717BBC685CFA525C110759B52F6AD9109F8F52BCC902D072C4FA90C37AA6813190576152625079216BC99B66FF178319E18DF7DDB088D891D2C0C30AA7E52CF2B7C0335FFE07DEBD2672962B823D1A8309FBA5FC8A66C6F706C7EA2CF82C183D215B556AA9E9BA6057003CB0FCAD674FB23B2466F1CB78EDE0326063705BB2A4D8211F5904EA79C6830733C8B9793669E4BD9366B15E44DCE6464EE54B5F6392E1730983396EC52399960A23C089AC7D63B +sk = C1B3CBFFAD4B306F9AF0CDD3028876486DBE858875C9B6497FE20172A986C82B1C96249919CEDC2369D8D739AB125E0D2CCB82DFEBCD90240A545CDFE07511F2F254CE4E29C707FF6C23D92678583701A615E593BE16AD92C8C000C56A7A09C5B793F477F26D379A3A2D3176AB97243738A80ECE4880500F37B067880903AAEB76D8A09B7B0C766F5D74F28F343A5EB0E605BD546FEAE1EE1DF9D5D30D507A8F53185A5A87698D9FD2F4802D8D293BF87F3FB09471BD5CE72612F712970ADB8F0087E06157C1A28B84AFB9A642D8DE08001F04777F5906920A54DB74672998321A1A9282371B13752B2919D62E90DF1E6E654786FA7E99DDB072AA574AFCFF8D4606977CE38F5C0A1AB1E04216F7667779A3E0E8AB3895C299E7CAD3B867A0BF90A447591C3E8EF5969B0A9974B2EFE21345EE07514A80EF4EDFF33E6397F19A09561D8F3D58B48FA555B7AE3F8F1EA2A728318ED4D20E2AFDFC202B8EE4F40EBBB76E8879B08D754B4EFA008A816BC07833BE03AE55136C4B5B04509A9056075490AFC3FA9A454E8340B86A65B1E96EA1A217D30788C1CEABF35889221058075FDD56E96181E850802AE946521750C0CF87076A074DA61816C4770E32F46A3A6C61EE551AFD294CCF17F3E9FD99D3E67BBCE717BBC685CFA525C110759B52F6AD9109F8F52BCC902D072C4FA90C37AA6813190576152625079216BC99B66FF178319E18DF7DDB088D891D2C0C30AA7E52CF2B7C0335FFE07DEBD2672962B823D1A8309FBA5FC8A66C6F706C7EA2CF82C183D215B556AA9E9BA6057003CB0FCAD674FB23B2466F1CB78EDE0326063705BB2A4D8211F5904EA79C6830733C8B9793669E4BD9366B15E44DCE6464EE54B5F6392E1730983396EC52399960A23C089AC7D63B +ct = 239DF62F111BE10BF18B9EF4E48305D5AE432D1CE0FEECF460642DC903265959C02DBCD1AC282A583B7E47152B343E88C9F70E1D43D6DC1CA2D393CD6AE517C4396F91F31F3DB0B5876B2D367424AEE12D3C3F9AD89C7180FA57069D9F2B7C5D661A5B0086016E1FE746FD2879B67EC02BE0D32DEACE1E284CBB6C70B0CEC6904FCFDC0691404A345947A8A7A118A8AAB9A85F7ED6689B62A03950D4EF1E87B5F7ACD312CA1404755C4749711A66E2E066B9D07202FE195859FAB437D2393B4827353207F40D2BCA1FA2904A857248D2E1175535D99EB09DA68B128374BACBC770799108600D7D23E564DF16B40EB4089FDD137D5D7CA3C015BC8710629E16DC7F9F71BFF7BABC765EB2D341CB1F7951B0427C9C6F13BB286B1F790BEFE6AA53BAB8271EDB84F404E47C797D74F244DD4159C79AFBD94D639C81F8CAE7E0773B90AC4ACE1249E1BA1E8C2B308F129C88758DCAC77198415B1F5CEF77F7938B0744FC7CAC9E6F98CCC8542ABC78A24E36361D32165D716A57D66B7B3DEC8D03CBF93D641738EC876293B7C38EB1FFEC78AB4F5C3985294E3E396D5FC751D39B59C2BA4DA72E258B0C87AFD64E4B41E7C65F0FF0B173D8813666FA3681A095AA5BC780C772D083E6AE14F9FEDA0F08C91ACC0F1D488C2B0F4AD1CFC3F0C6BE3DB3580A7234107055DB881AE938B4CA3FA40128FBE5B778B6508106C4D0501B82F74B4A8A01B4F9759A941E03A0229A50E42405CC2BD72B1C5767DDA57DB96CD1572F0275A8FAFAF18E33FC1D8F1009322D98ACD929A5D52A6B0EAB98837ED67FB808423631948C9273D532BA36ABDDD142277EFBCD +ss = 9D5CC018D88D15BB1A5D3D7AEC6770B93F101F92403A890AE941A63A8734BBBF + +count = 47 +seed = 730B65ECE22DE27D573CE3AEA7CB021C415DF210D228808D91D4F380070FFCB0778B683C71D4853DEB569C822765F2A3 +pk = 8E23CA5B8DD16E8ACFB13EFB2DCAAC8D8EB1BB7CCB619ED45C571369E2C5352C5F160C3A5EF6E3DE4F4ADDC140FD40E02CC502D2050216F7FCF45C11272E2368CCFBE715A3008E7D9574F30335A453CCB2E9B4E153B13534A63EC9478534984291CCA680B95255BBB397E4F0067FD952865C1D80150DD810202B2770F2E5D845BCD1068D71180E4AFADBE7857689865565FFAD58B1C4B2A36F261F911EB5B9FB5EA625771B3F9BE2021F7D66DF5E0B94C26FD09EFB5DF1464720F91F4E1E4D67D6566F85A8B388D031880A03F6ECBEAFD5E6FB62C2016D264FFCA68874E0C96E3D05FD5C9163A6CDA6AB06A2374A7945AE48771BA04C8B46FE7CB4E664269115229172EE96F40DD2E3FD7E0DB25C3A331CC06725A2800B858A0A60EB014C683BFC3F96C348BB0086A51F751F3FDD47D47A087C45B53900C1ABAEA22E77D3FA9D23C973AACBBF6F46FCBADFB66C5E39026315B0DD9247B7AE280778E765FD2E5A3BC489FBCD62876E54B91DF6A9F517A296295363E0B0C423BE04263AD4191AE763A04E5C37207648053DE31A0304CC9E8DC47CF77449EAA42479A18D2B48A91D14E3DDE69AF4FE9885F93F9738A5B3B35B5DDBE43D9FF408AC47C9450A5715B0CEDD39D9D4A5171C16331178B88F35C5C44A3AFD95491120680B9A33002B41085C3879CB9AB26729F0627AB412729A073D659EFD82965211DD1C7FFADE02654170206E9D749A67C34F0B777E0A23EFF1B1C06E49230766B568C1D14164E283E7AB27DDAFBB3BC12F3D3B7E9186D761A31C3AC50D +sk = FF7495B8575B5A98E4FD21FB4C3E58CBB60F14BEF21AA74CF8802E3153F14807BDC370460375A778D1A31D01C42B66367ED8D9E8F84551002F552F0E52102B5D1079345C46623B897C14635FB5051B038E23CA5B8DD16E8ACFB13EFB2DCAAC8D8EB1BB7CCB619ED45C571369E2C5352C5F160C3A5EF6E3DE4F4ADDC140FD40E02CC502D2050216F7FCF45C11272E2368CCFBE715A3008E7D9574F30335A453CCB2E9B4E153B13534A63EC9478534984291CCA680B95255BBB397E4F0067FD952865C1D80150DD810202B2770F2E5D845BCD1068D71180E4AFADBE7857689865565FFAD58B1C4B2A36F261F911EB5B9FB5EA625771B3F9BE2021F7D66DF5E0B94C26FD09EFB5DF1464720F91F4E1E4D67D6566F85A8B388D031880A03F6ECBEAFD5E6FB62C2016D264FFCA68874E0C96E3D05FD5C9163A6CDA6AB06A2374A7945AE48771BA04C8B46FE7CB4E664269115229172EE96F40DD2E3FD7E0DB25C3A331CC06725A2800B858A0A60EB014C683BFC3F96C348BB0086A51F751F3FDD47D47A087C45B53900C1ABAEA22E77D3FA9D23C973AACBBF6F46FCBADFB66C5E39026315B0DD9247B7AE280778E765FD2E5A3BC489FBCD62876E54B91DF6A9F517A296295363E0B0C423BE04263AD4191AE763A04E5C37207648053DE31A0304CC9E8DC47CF77449EAA42479A18D2B48A91D14E3DDE69AF4FE9885F93F9738A5B3B35B5DDBE43D9FF408AC47C9450A5715B0CEDD39D9D4A5171C16331178B88F35C5C44A3AFD95491120680B9A33002B41085C3879CB9AB26729F0627AB412729A073D659EFD82965211DD1C7FFADE02654170206E9D749A67C34F0B777E0A23EFF1B1C06E49230766B568C1D14164E283E7AB27DDAFBB3BC12F3D3B7E9186D761A31C3AC50D +ct = 1434D5ADEB3705D1F75759E210B9D661AC162CE9AF2C0A79E6731D3AA41FAC7D3483CE63F213AEEDF5565DC38607191A730C3880E9D4F4D873576A05C0C33358D4A7F4D95BBB71DF931F88CDB587CD7E64FA7790F803FED92AA1DD659B337CCF71FD0BD2961A0F024C9D4498976EFA6808929029371E17785543AF98F1E77DFFE9AF7272B74BB6060A299D8E503AA9EB395532601A2853E8639199FD3EB75EB903A1A2FF9DACC9036B2C4DD14691968D4682236AB5C1EB615348B35C0C8049E77CF752BCBE707EA12F90E6A290B81FF0D42BEB1FC70ECBDD5D7930AA59DFC0B73F23296498EB9A1DDEF0CC95EA08444E884BF6A2BB5765BEB2ADA4EEAFC136C1DEBCBFD5F883536554D027EFD2B57DDD860C2F4686218415C705F3EA956BF4C87D3176F15D8D44FFE5DEAC3CB5C88D835F301A6B64D40BECCF286092A64F3E0C039DD0076552EA02C30E2554B553AC8D379EFA0786A1CA07A2EBC28C7691E2516CE6213E8FE1522CC379463C9ED2CDA7978E19A90911BA0EF48BF7151746E89E05F9C537026041891057B25912D77A066014BCC79CA1212F7841512E6CB9ED0F500AAD18F9458E40FF1F78942749E8206D8215DAB0B6234BCE58FE66265D960542D82E6C5FADFAF5B681360B47353C4C54B604450E28DE1476CFDE211663F14BFF2DF9AF9813A2D56B7BFA8C8D63F8978C193BAF1219C3A6D764DEC36366771AB29725E02C5B5E8618E6E9E841AB728282FACDC9CB53924C4195AEC0BDE31323D709BA437A003B6F815F03C2BBEEBF6736C6DF0512A09CB7D6156A6CC51F84F2BDC8C8A5994A10DEAEEEB62345A488ED5A640BF2 +ss = 4C1117E3E10F8035448ADAB5EAA7F03B204B4D6319887D11AA75678EA6304FF3 + +count = 48 +seed = 5522A5A891A9A9B5514F4556AFD8DF40B9CEC63A01492F0CB8A1DB073A285A963E4A9FF2376C88662F7D8D241F8ACF17 +pk = DC74114035A37B5328891E908AB48E3D663B9E356835F50D821E9B67C199F43B5A1BB1F6B67390DEBF8E6BD88933FBDD1C88BE423228D3C753D4BBBE6CD5BB05A12FD0F07922C0427AB0FBE5101608A3BE583FF5BD318C85857D8D2567256665F2DF31195D21718008B1AF1270E8910E804E78D1B84370A6D2E51E6F10DB3F35030E9E96E6A8D7D034BD217CBD193A8D9EF1684D0AB0AF90FD8505BBC55D2EBA9D61025167DC674CADDFC70E9F36716BA8563B3344F2D9B5D0B69419D21D03BECBFDD64630EC9EC5CC0B9A98D54A3A8129BF40FA2D02DDA6D38AED591388074A134CD2FBA03DABEE6D819422C80C7224A10C0359BF8FC9442A9CA8B42B074BC327707BCFBD539FAABD2FD813E0F62EF0E0B66085ABE9E692934C86757FB83182362AE7D3AB32BB7034B12CCD4A25C3E46C0BFB8D4F14C41039A4638457BE60B4D8501E258B38BCF3ACFFD40C8DE77FD8FB0C5113278203712FE2CA365B7A67F216B0D0F5E2004DE1BFAA3EF8893E6D1F8BAAB9561AC6C23E0959CFD7F0B33B557BF95F9940C624BD6EF7EB5F25367C766C5DA650E68CBC200B7BFA056DCE8F8D2882560D0BB3C4970905F2437366A958570B7B8B997009BCB90A82D3FA7DAE4D2331D3EB55B7EACD330184803E0359328400499D2D3922360EF8CC47A0055E202BEDEF49ABD84A3F46C0E0DD5347778FBA5727561093B91B41A5B68187822D29F3B4CD0E0BF44D0BFE6E20E2A4DF8A0F4E02B102BD5C80882AABCFB6DBC0E3FA1FCEE6DB6B55B53F2F97D39075CF8A1681511562 +sk = BDC3FBA1C32751139FC45BACFFB3EA97F26573D804A5F27A459293D95190ED8EFD5A08F656A6EB8CD20679930A31CAA6A6331C4B133A6838C223EF9F769F6246B1C126AF949A371C0C30FF2C2FA35300DC74114035A37B5328891E908AB48E3D663B9E356835F50D821E9B67C199F43B5A1BB1F6B67390DEBF8E6BD88933FBDD1C88BE423228D3C753D4BBBE6CD5BB05A12FD0F07922C0427AB0FBE5101608A3BE583FF5BD318C85857D8D2567256665F2DF31195D21718008B1AF1270E8910E804E78D1B84370A6D2E51E6F10DB3F35030E9E96E6A8D7D034BD217CBD193A8D9EF1684D0AB0AF90FD8505BBC55D2EBA9D61025167DC674CADDFC70E9F36716BA8563B3344F2D9B5D0B69419D21D03BECBFDD64630EC9EC5CC0B9A98D54A3A8129BF40FA2D02DDA6D38AED591388074A134CD2FBA03DABEE6D819422C80C7224A10C0359BF8FC9442A9CA8B42B074BC327707BCFBD539FAABD2FD813E0F62EF0E0B66085ABE9E692934C86757FB83182362AE7D3AB32BB7034B12CCD4A25C3E46C0BFB8D4F14C41039A4638457BE60B4D8501E258B38BCF3ACFFD40C8DE77FD8FB0C5113278203712FE2CA365B7A67F216B0D0F5E2004DE1BFAA3EF8893E6D1F8BAAB9561AC6C23E0959CFD7F0B33B557BF95F9940C624BD6EF7EB5F25367C766C5DA650E68CBC200B7BFA056DCE8F8D2882560D0BB3C4970905F2437366A958570B7B8B997009BCB90A82D3FA7DAE4D2331D3EB55B7EACD330184803E0359328400499D2D3922360EF8CC47A0055E202BEDEF49ABD84A3F46C0E0DD5347778FBA5727561093B91B41A5B68187822D29F3B4CD0E0BF44D0BFE6E20E2A4DF8A0F4E02B102BD5C80882AABCFB6DBC0E3FA1FCEE6DB6B55B53F2F97D39075CF8A1681511562 +ct = FF5180A00E8D3999AF930DC3FE565C73CD76E1429BCBDF600D3A80D268DC86764BE58CBA103F6D4C3808B0A8D1229E29FB245A3F36B80108854E845E26544D14AAA77F378F9C045FBED6F1CA39F9A613B2BC17C867AA07F194CC61BB5D30556508157617232E70644908CE2D0EE75D18A82B331F573543E63904DC4217A21EA9ED279B1EB6A272E69B639DEF9D50035384B49B4D5738BCF12E7D6B431BC60EF4AF8809C370F8C36773CD1ECF4AC7EA7A2F016D64AC1FE6AA98211123BED06FC0DEC213929D85C4609BE6E57F2A2EB908C389CE11986C50CA487404958B858D36D94A152886D9184E76057D4DCA954577BA2E0B9B8E5168F4076561134D4C4482873C6A8EE6778544A2285F444625B93820F0288221B6688BD2313C6136433FF4ACEB3B84BA04AA0BDFF5534A11522FB960C5E6D9BA27BA153B009D7024C746C8521DC4E935B72732BB7BDDBDF0D65124EB08E47D47BAAE9B030989D8C939CB5443D2EBFC9C2149E19CDBD80CA40C5F74B07BE5BF1B941F59598AF769B8E97BD971C0342F578B07D32AD30CCF6BF6BD09DB1CE2392B5FE73BEC2E030374F8794D79331969DF21E07312CC562BF3E2281B439F7877601E5BEA2180DC681EAFB233372293F0F2784AE50D4A82DB455F4E622749C7B22B47DF45542C24DA3C4C7E050B73E403D1ED3D39806F4C5BA8FA2439D815E26127B2DF3D8768D900488E2BE98E88A9EE9E8A96DF26FAAEC5B9680175B05BE43254158D4A8463F74913D5E6D5C09F0542B2C77A32D5C92AD68555EB90CC040A6E0C818B83606A4F4AF9E645817AAD4B7EF6FEFE423C394B38D82CF14E1AB6EB5F +ss = 4ACEF422DBB0D1F49DD4367046C29FC7CA96FBD872A025D000DEE4CCBA6B8951 + +count = 49 +seed = 1853E72329353B3F89AE6A1B1EF700DA8ED3C10D19F9E61EE9252E28EBB0E15802EE43083A12A0B7527088832605E3AB +pk = 6A86D41BD20C36A56AD76089DE620F4B6BBB9F9A8B0DBEFE95D1B9694EB3F4CBED172BA94C3671DDE7D37EE39C355B9DA0EBB3A434524C72DFC066DAC3650E3325653476D31D9FB8B17350DFC880137632B0CB45630F6015DDD492345334C115D10986F6573B55121935702BBBC53AEAD879F5F9328D61037D1D9EDA992BDC63C2BDEFAA604CDD28EF2835800451488E15F91CD42F7BE6665AAD2639E738EAED77F7E0B855568148A5DCF89ACF2FF76A5F8420BDBE60E5A6D9EAA30510F82B677BF1C0D790B356AD8D6069A3FA453AE67A61962B84535EB3A737DE19E37FEE1898549471568C443A70D59B27FD07BC16C05B1FBCD7FE44732FAC42AB677464D9240E8D5304A384828367D94DEF4FCEF80CF4BA5E5C02EED88A603D19843929DB0F3929CE0732A56DBC6620338269300DE739AFCF8800DC9DEAA84DA0DF4432896A3E831A69B53222BEFC4328AF0DEA9DC795821DFE46A3F6B07305B38F3C288D4A60F5FD3D1D515BF41AD73B828882C9EE9C9863FBA3453A19FD513447B742301FDE3DA1742C8FA0294A8A4EF0E7FF03C073C265AC1284B5CFF01B06D62E1E7318DF606EEE1CAE5AE5709F5980333CF367B01CB71E3EF93DCD314A0D43B300EDF6AB3BA360C3D4240E3C61635D27FFAB79F2F31DB60F0A7E1ED0307037FAE1463BF2DB4804499B8FA4E9F667F2E4D70B8221A3D7610D7F6E7AE6B8ACDE68112E965C77170C7A4F420DF5E39CDC5EB10AF400392D017C87338285F9F7FD1DE3548AB2FD24BE767D075FFDE951144D0D92389F2E11 +sk = 447F6076A627BBC5AD7773FBFEB14B4BA9AC43A0F8B99FB6DCD5E452AA3C47EC20A7237801F470FCC2BD9FD7BEA8322859B850F7882D362947432913DD068C018947AAE799ACCE17FD368D5E1B6C0D006A86D41BD20C36A56AD76089DE620F4B6BBB9F9A8B0DBEFE95D1B9694EB3F4CBED172BA94C3671DDE7D37EE39C355B9DA0EBB3A434524C72DFC066DAC3650E3325653476D31D9FB8B17350DFC880137632B0CB45630F6015DDD492345334C115D10986F6573B55121935702BBBC53AEAD879F5F9328D61037D1D9EDA992BDC63C2BDEFAA604CDD28EF2835800451488E15F91CD42F7BE6665AAD2639E738EAED77F7E0B855568148A5DCF89ACF2FF76A5F8420BDBE60E5A6D9EAA30510F82B677BF1C0D790B356AD8D6069A3FA453AE67A61962B84535EB3A737DE19E37FEE1898549471568C443A70D59B27FD07BC16C05B1FBCD7FE44732FAC42AB677464D9240E8D5304A384828367D94DEF4FCEF80CF4BA5E5C02EED88A603D19843929DB0F3929CE0732A56DBC6620338269300DE739AFCF8800DC9DEAA84DA0DF4432896A3E831A69B53222BEFC4328AF0DEA9DC795821DFE46A3F6B07305B38F3C288D4A60F5FD3D1D515BF41AD73B828882C9EE9C9863FBA3453A19FD513447B742301FDE3DA1742C8FA0294A8A4EF0E7FF03C073C265AC1284B5CFF01B06D62E1E7318DF606EEE1CAE5AE5709F5980333CF367B01CB71E3EF93DCD314A0D43B300EDF6AB3BA360C3D4240E3C61635D27FFAB79F2F31DB60F0A7E1ED0307037FAE1463BF2DB4804499B8FA4E9F667F2E4D70B8221A3D7610D7F6E7AE6B8ACDE68112E965C77170C7A4F420DF5E39CDC5EB10AF400392D017C87338285F9F7FD1DE3548AB2FD24BE767D075FFDE951144D0D92389F2E11 +ct = D70ECCE068BEF9327ECE8E20430A934C8B54FA7F9245C0E8F9BC71B42C7A20949F4E451C1DCBE3C8096A93A1BE8E86059C66EADE270DAC336B4ECB3AAC07E0BE0E027D327CCDA4B9D094ABE4E95CF1F8038A52E85A2C43D56D50BDFCB812CC0CE265900CF4593BBE9D22DFFA1F37803FDD833F3825F37417304D88100F1EFCB96C9A99FDF39DCC598E5A5F764C9377CBC0542551DCD62CDD6EBE1AEF7601FC33C283EBEF64B91F0238EB2D4D499EE8F9263D1D638607BEBA1B881306F742BB8230052EC52B6832EC8FD80E8FED8F300FCE5977E1DAF15FEE8E3FE6FA497B747541ACD581A50D4B52A82B8A89D8190030366F9060E4711A156715BAAB86A299E66312E35F718476E37FE4534C871D75F28BB183389D0A0F4AF323788AC0B9A6175790CA9C42442AABCC43AF48BEF3C0C57E4D13E2E961B00122DE4DC91EC87BFDD489889FD692D921BAA4984A031ED33444262E00216D86F911459F14F9D22BCB554134E5B245F1561913F6D63C1071D460A554CDA480EC638136848873F6A5C7E33448E6050E9C93FFA0F1C2DF79F59708AED911E2ADED8C6BE8871DC5F2F7DDA795A13928FBC89B2BCEE9C25A08246224CF4B5229509664CC18DC91E6A2A24F9567D943D7AA65DF35C43B3611C4D129C755E147D34383613DC946A7B01AB87A2FDE07D86E3E747BC90A1A40EABC14AEC1026E40BE2490136680D05B7B0F84234AF801E1E6F3B4CCD125514F51EF209B8A73CB3C68C918517CF70073CE4FF73FE0FB5706F0DE70BF529A0B4DD7FD18FB032051325756CD1EC354E28C46AD47EB314727DF8BB7154B879B71D14406EAB43D707F84 +ss = C54E70E7194F597FCEE8B17013B77285223253A43FB6EA82D32C532ED4E4F41C + +count = 50 +seed = 027C3D5847ED4470931141104F25B19AE76117CBB64B224EE424FFB782E9A0E988839E0BDED0DF666FE8E5FCBB5DBC09 +pk = F51F51D2278E6890FCFA73FDAA12F112BC7CFD5B3B88E59B630B7D12D0F44A63A6E0ED43B064663360DD83FF4CA122B7E14CD3A350CEA4CB263F8E283006A84A06F4448FD93DDAAFDC88B8F410E5C2EF8925DF331D0A05F1C79021C99F00CD4FD17ACD0911489E40A895F2F7F8D1BCCEB91EA54E4206C2A6092F069F942821E0F98D72A9ACC0D72D1BE115EA379F85CD8DF484BB6135CEA7DD5EDF99CFA73696C512F26346C659A57BB812DD73E76C5C4587FB8BDF9AAC2A19A1E32FAF3DEAB64093EC175D4932336C2606F804AAA923BA14F25158B30BC6B389ADE5E8FEC02818A2B5B97FADFF918BE47C199AC607FC8B4BF93EF38C689A1F55E8181F48D5563833B5FCEE5173C812DCFF2AE7137261F319CB96CFB80D150D007A07ED5C886A874049D6105EB5F774DDEEFAD84F9B67408468C925E0B8D3544D0B315A19B3BB71EAF837C0029ADACC1CC09EF12CAAF60D86C96CBC49CEAA5DFDA7752BB1ED23714B85D0BC79872090F76ACDCAF53718B79E4F13866AA95261BE911096F5ED80E29579F3AF5FB3E4EFDF9239655EFFC0416D09111F3F376F2DD529ABD91D80DE64F0DEE88E31790F569010CA3D3640679707CADF9235F15EA163A8273BED7FDD34787C10FDF7AB216EFD37C37646CB47C76955598148F22E7645852050CE9B78BB7A2DBA8EEBAC8E532A6D7840D7F43F7DF4BF16A78D13010B3A6BF7F36E132BA9963F474F0A9CF69420D6595AF7EB4CDDDDAD88574132CEDF9F3812998341219D27A68544E9475C6AA6F9350A06D6AE15063E53 +sk = 2D5DF64D62CB07FE630310BB801C658DBF3D97993E68626745DE39D37FBFC2B27B534537ADDABA4ECF14F02AB317D36CB9F0F50222CED7CF029DFF8A0D3D2FD9AD11C88352139F355097E0FFB2E7EE02F51F51D2278E6890FCFA73FDAA12F112BC7CFD5B3B88E59B630B7D12D0F44A63A6E0ED43B064663360DD83FF4CA122B7E14CD3A350CEA4CB263F8E283006A84A06F4448FD93DDAAFDC88B8F410E5C2EF8925DF331D0A05F1C79021C99F00CD4FD17ACD0911489E40A895F2F7F8D1BCCEB91EA54E4206C2A6092F069F942821E0F98D72A9ACC0D72D1BE115EA379F85CD8DF484BB6135CEA7DD5EDF99CFA73696C512F26346C659A57BB812DD73E76C5C4587FB8BDF9AAC2A19A1E32FAF3DEAB64093EC175D4932336C2606F804AAA923BA14F25158B30BC6B389ADE5E8FEC02818A2B5B97FADFF918BE47C199AC607FC8B4BF93EF38C689A1F55E8181F48D5563833B5FCEE5173C812DCFF2AE7137261F319CB96CFB80D150D007A07ED5C886A874049D6105EB5F774DDEEFAD84F9B67408468C925E0B8D3544D0B315A19B3BB71EAF837C0029ADACC1CC09EF12CAAF60D86C96CBC49CEAA5DFDA7752BB1ED23714B85D0BC79872090F76ACDCAF53718B79E4F13866AA95261BE911096F5ED80E29579F3AF5FB3E4EFDF9239655EFFC0416D09111F3F376F2DD529ABD91D80DE64F0DEE88E31790F569010CA3D3640679707CADF9235F15EA163A8273BED7FDD34787C10FDF7AB216EFD37C37646CB47C76955598148F22E7645852050CE9B78BB7A2DBA8EEBAC8E532A6D7840D7F43F7DF4BF16A78D13010B3A6BF7F36E132BA9963F474F0A9CF69420D6595AF7EB4CDDDDAD88574132CEDF9F3812998341219D27A68544E9475C6AA6F9350A06D6AE15063E53 +ct = 7515BB17FDC699E6091DDD810FBA24E05BD134B399B79F121886339445F47F68D8CD7ECAFABC695F8FA1193265CE6A17D8D765B9D87D957D35113C47D4500752DFFEF5B7A15199AE7A3929E1032512FF1062FE8E61D94D52AFE47E39A93FB14F728ECB51A2069DDFA8EA7B45D109F54A22D43E1A775FEFCA7DC950CC4706933CB0A7586B12EA5F5B447E39F00191ECC19AADD931BDDE64C7C1BD1B8845E52D60E6B6CC179814844CE2E911F0D1E64953A2AEDED7C2B63FC610E9B5646AC57D31908D15493B19713BFC61F451A21A655E32D4CF80EF11B5CFBCABFB1B5B7D6749E4656A6A3D0DA7263BDD514A317E432341585072BF5C0E716E159DDF3F6B9A1E55E42E931E51099B5EAF5A7986EA89018803CA1A5867EA9F8450DE4987734B0B17E4CC20586E82D15E35B8B3B9BE29F117CA5181670178DCFFF8591B85D0AE37264161D35FD48C0CB4303A7E57A523622F25A2266A67BF717E584FD9048B484EBA7D424036EE787D1D6CB478A953F3BD6B1FD85158B03F0E9E5D29B5BC3E9C98B5A3FA49AEC97098976F6DBD8E1BEEC45EB7A64645C034CDD86C26888D9F7D11BD18B6F9F151C5106CA152881EAAE69201FBEEBD2DFC95ACE377FB9446D24F89F1441E25BA66614AA42FC293C034CCEE2DA1FF19822862CE2E56743F4D1AD2C82EA6E5DB7280CC3CF7DAF5D8F3B12444EA63EC98D4924BFC310319B177C2B3CE63A844D26C926FB78515B9FFBEBBFCBD60F0842DFCFD050ACF303ABEFE31918BA1B1154335AA2D242E2F0EBC0B0AF4CCFC81B94662BA43A91D2BAC1A74A08C2B6F2380E03BC9804A2CE1751475982893FC4CF73F +ss = 828E97638076B1AE2CE45C961FE4A34315EA7AC451F95731A2A1A569977AE047 + +count = 51 +seed = 450751D4401737459C6D93E6C5F2FBCC4A3AF7CD7250CCF404BBB817A67BAB7B4C9D0EF4570BFE25CF919DA331C31D88 +pk = E9DCB5C5F61215CB1AD2397F85571D5006640CF57680B3302C06A39820C0CABED8B14FDB2067242CCF06D739254D80C23CF11E126DD64262961EB538976C4BECE2BD01D7F004CB3253BD876F6B7C522B2397E4BCC8E9E3FA248B43874F3890F1A41084C19C524C6DCBBD8A0B88976D33AD39DAA75CA1B88B81EACBA2577AB03128C08595B8CF8DDF20A6A6B3E0FBAF4822BDDD1938E3448974A8B47E6B5A682E6B0452015467BE05EB98E346CFE518FBDFCF0B251D622B271FAC34592C34B6D7BFB84D321FA696ED48D67BE35168528E19C47E3F1F480B078D9B88CE3FD6C28382DA96280EF4FD5B47B7EC08EDC782B694FACB82DA086147BA1B3D72479537C7246B4A512E852A25A2EAA642F01BD35EC6E833EB3C8BBB4EB90C37E32A2DC1220C1F26C56CD9295532531FAD57D659E7363A377D902F3C40D30B806EAED2FED9AA38F8879E5F54F273CB77AB6AB72DB19A51706DABBE6A7487E23A6ECC05D84E07E54606038419971F8BCADDC6469FD3B20D944AF9424927A9969A6E4D77CAF17AEAD69126ED4F10B32CE0AA1BC02A7DC0DA6020A9EC69C31A2CBF8D9FB4565BD3DA46FF5E85FB3D476E44B83BE592C5F0B1C5D7FEB7D597B7DA6C3C996EAEEA8DD313BA9B629C82FD598C3935B7E8959CA093E0AD4483CD1C2E8B79EC9743BFFF0CB9246DEF796CD597E10740146276667DCFAF264F7F9464B3E627E6AFC2624A821500E2726B269CF33852A838687329C889D26F6BE8F7995C088751F7185EE8B71AA7FD844A6311136D3157425E79B427A537 +sk = 25056D1B8113BB362DD979D98643D7A7AC9C4F95994C0BA060609B6D07002FF3F48A9254DD40B117941FA35A66BB50296327B725525DEEF70E128CA8045EC45129C76D04EEF82CE39E21F4C96A5A6701E9DCB5C5F61215CB1AD2397F85571D5006640CF57680B3302C06A39820C0CABED8B14FDB2067242CCF06D739254D80C23CF11E126DD64262961EB538976C4BECE2BD01D7F004CB3253BD876F6B7C522B2397E4BCC8E9E3FA248B43874F3890F1A41084C19C524C6DCBBD8A0B88976D33AD39DAA75CA1B88B81EACBA2577AB03128C08595B8CF8DDF20A6A6B3E0FBAF4822BDDD1938E3448974A8B47E6B5A682E6B0452015467BE05EB98E346CFE518FBDFCF0B251D622B271FAC34592C34B6D7BFB84D321FA696ED48D67BE35168528E19C47E3F1F480B078D9B88CE3FD6C28382DA96280EF4FD5B47B7EC08EDC782B694FACB82DA086147BA1B3D72479537C7246B4A512E852A25A2EAA642F01BD35EC6E833EB3C8BBB4EB90C37E32A2DC1220C1F26C56CD9295532531FAD57D659E7363A377D902F3C40D30B806EAED2FED9AA38F8879E5F54F273CB77AB6AB72DB19A51706DABBE6A7487E23A6ECC05D84E07E54606038419971F8BCADDC6469FD3B20D944AF9424927A9969A6E4D77CAF17AEAD69126ED4F10B32CE0AA1BC02A7DC0DA6020A9EC69C31A2CBF8D9FB4565BD3DA46FF5E85FB3D476E44B83BE592C5F0B1C5D7FEB7D597B7DA6C3C996EAEEA8DD313BA9B629C82FD598C3935B7E8959CA093E0AD4483CD1C2E8B79EC9743BFFF0CB9246DEF796CD597E10740146276667DCFAF264F7F9464B3E627E6AFC2624A821500E2726B269CF33852A838687329C889D26F6BE8F7995C088751F7185EE8B71AA7FD844A6311136D3157425E79B427A537 +ct = F302EF3F9F5B75304BF93384717C94D7779781DDDEDC3DED5F44D7BB306C90DC8493B0E1755718C1F63053B7E2910B341FA9C21BB598DC80C150E8719F1E9C55B3C78CD17F76A233046C5ADF5A3047DF2C66A782917789B5124296FD11230D9808BC84E29449C41B2250C3A87827DA8C73B24C5F5D753BC7DFC5A0955CF44AAB66C1D0CC6F70531B15ED90751A36A2A3BCBB214D7F6439C6B8955876160F4D008C2E0822D4A3D2E360BA2C1F60B473D9852ABD73B57854E3BD3D68468C376B568192EB96211BE343DC3BD57267BFFF476A41D2E963AE67AF124ED19A42E9D0E25DA7A2D87D90E6CC25ECF707DF4D7D456DAAD30B2B1FCFB2DCE279DE595C64CCED47BF4F21AA33C801AB78C5756D879C44A02332977A83296F1BCC0F43E6859749C32E0D4D9920A1754F3D415E28EE02CBFF44677EE06338E4C4BFE437AD8CEA1765BDFEAA28969CAB7CDDF123820A7872E0E1FBFAC8675C2C995AFE136B22870F4D0DAEC8684CA52D2B7D2CCE9167FD41ADDE6DDB172E279D49D7E39A3555B857291D6F8571C74297930DF4633DBA5411E52460BD4F218FD0A187EF132FD37A2F79D089152E4100C5A5AEB608071276FCA5AF35BBEFA9F067919F9E8EACDBCCFB31A692DCBE718D5B25EE4AEDC15227B1A113E1166EA3724B5FFDD21096E8A2BDDEEB668DB5CEA1712B9C956177683E4FCDB5D382108D8A3AD88BD468F302AD4E5B0959D919C3E871AB8FA6791E450654DECAAA9F12C4A615C3DD8997C1337A8C15D2AD36DE8FDD985518DBB4A483FC1E81163FE4FFECA51A31DF426AEF0C1D3766AD23DFB2C7DB846561686D5AF52C37F4DD84 +ss = 2798DC47E7CE8E60B363CA03CFF8B45F2EA8A302D781EA9E441E7643D0446DAE + +count = 52 +seed = 5DE720F2D152BF4E1F96A61E7AE5F1BED6B8548E32638C2CCEC9F43B87D1BB43DFCF334F0582984D27E440D519AB662F +pk = 8BAEE6F5EFB85C4A82C457B89CCA7CE86A450E423E902E36FA5714804FBF9D7307939FDD1A8A9C0AABB219FD171EBA0E8BFC27C976BB4F34034849418925E79BDF4B28815761D32444192D7F66B41750DFB60CD1982EAD1C00ACA7D5FC563B7CA3CB95E47AF65F31E8606B1E7564DFF3D979D3EA5023385209C628E5D58C29CAFD15C79BDE7330EEB4050ABCAC7B6848617CA93A93B14D5961820D9E5F7F6E3ABEC8308E4C7826C70062A3AF86E7361BB80F630D2108512506EC732ED606B625B45C6EC4C8EF3209D2A88DBEF67F28DD1A79A5523017B1BD77682D09DEA4F6E08E5370394CD6159EEDDBE17C26FFD1ABA69A6F2CFB3AD4CDBF2A48B048343F3A653E2CDB8F3A369A71E3C3D95BCB26F4CCCFD2FCB5E6395E1F6EC070CE26A7C99718F9127EDDDA20963F7B295D6B1C54FFC1B5D6C144A9DC7584B641A086F4427629337B63F7C47EB55806A70AAB5084482C84D52655408B3AD78237D64AE9BA7226DA0F69036C54ADEEF12B16B0D2DB3F244B802CCAD42168A352004836C8FA1F2958E228E57B6929703919D81A536AA4AFF3CD824C726A05F630A5A3571395D3DA67D89C29B68E76919B9C9B6132707137C8B0BAC4284B209709A83981C23C6B3FBC12486432DA559324E65F596D966046F7E63841CBA48ED450FECF06AD2E166C09F90D6C15B53894D815E492A2075AC777A83C4004125B6B773A1315615BD3DCD75EB719525F87AF367B9E3F245CF623FF7FF4F3299C07B5488FFB704417D7B50A1C8D2E918A511F01C8ADFE3EC45807FE13 +sk = E4D34E12982AEEB1D62FD488D9B9E28557ED3429292239FB4F76FA9098009ACAE6C45C7FC62329B13C8D29844405DB8FF6860DE474BF727ECD19E54E6E1A141BE969CCDB4A327CF359BF5A383E2A90008BAEE6F5EFB85C4A82C457B89CCA7CE86A450E423E902E36FA5714804FBF9D7307939FDD1A8A9C0AABB219FD171EBA0E8BFC27C976BB4F34034849418925E79BDF4B28815761D32444192D7F66B41750DFB60CD1982EAD1C00ACA7D5FC563B7CA3CB95E47AF65F31E8606B1E7564DFF3D979D3EA5023385209C628E5D58C29CAFD15C79BDE7330EEB4050ABCAC7B6848617CA93A93B14D5961820D9E5F7F6E3ABEC8308E4C7826C70062A3AF86E7361BB80F630D2108512506EC732ED606B625B45C6EC4C8EF3209D2A88DBEF67F28DD1A79A5523017B1BD77682D09DEA4F6E08E5370394CD6159EEDDBE17C26FFD1ABA69A6F2CFB3AD4CDBF2A48B048343F3A653E2CDB8F3A369A71E3C3D95BCB26F4CCCFD2FCB5E6395E1F6EC070CE26A7C99718F9127EDDDA20963F7B295D6B1C54FFC1B5D6C144A9DC7584B641A086F4427629337B63F7C47EB55806A70AAB5084482C84D52655408B3AD78237D64AE9BA7226DA0F69036C54ADEEF12B16B0D2DB3F244B802CCAD42168A352004836C8FA1F2958E228E57B6929703919D81A536AA4AFF3CD824C726A05F630A5A3571395D3DA67D89C29B68E76919B9C9B6132707137C8B0BAC4284B209709A83981C23C6B3FBC12486432DA559324E65F596D966046F7E63841CBA48ED450FECF06AD2E166C09F90D6C15B53894D815E492A2075AC777A83C4004125B6B773A1315615BD3DCD75EB719525F87AF367B9E3F245CF623FF7FF4F3299C07B5488FFB704417D7B50A1C8D2E918A511F01C8ADFE3EC45807FE13 +ct = 0B4FBD4A5097A7265728C2EFF1C4B72EF2E075DA4456E65C035D29383822B75A063EC193FBAD0491FEF2984A1DF8F42E8E1CCB40065FA97DCE0BBABA821B925F3209CB8FC39F5EDBAEB3AD04EAF643FED01171B4596D474D17E241305001B8E0B23EAE45E87B1744CA0A4E9E171C844B1CC909E71EC2F23E94243D617C11BED8903EB96C99F980FBC78B349D52C9727857819E9155350B8FCFFF8FCBB74153BCC2C8760BD1C1D3464733BDDD67114781D839477AC685C7E32DAF0155FEDCBC6694D5FA194E7E3BFF071A0A675FC1E262F5AF8DD475A2C2DFD5BC278A6B168564AF053C3DDCBC6926FB049F4DB4782036923D494802022D61D80DF9FEDF9CC35BD5BCE3B0FFFD61FE9E0ABD169446F908137E8C73C8B21B4F1420C2195FA78FF92F5CEF028CA1F3026C6F0965FEA4DBE9DA80602BE51AFC0C34EFE5DEF21052D74AF03A6371206A46157BC39FDB8F2E30C7C44C31474DF5D45CB61AA584F02A55B5FD3BB8B89D48E25512E789C33162F26A82E44196647B219420F579989DDA81167C88BDB8E61E6D72E7780A6850B9457D87020A8326CE2A9D1536BFF653EF3CFA86E56EDCCCAE890F71BAA5560272F0D35A3715B39416023874B717084E7C93A1B05BF097EE04FACF747160C0A52128EFF2E6F0153FFA2353F330807B67707094451DB2BCB2948E464ACEEF3DC350F266D773E621DA3450CE044899E20D7F10577FF07A68C6F6C27D55D6974139597166E714A7EA19790C146E7A864DE051A63EE7C29ADE75BEE3BB5A3D7F8FE04DC8AC15BE2D9AEF3C690E3523FCA19084753A57BF21B5D1F3D87675161FD2C8613BE100BD03 +ss = A9CC3793476808A1248911D3B0D7DCDB32CF92575AF827FF5E71DC9FDE6033AA + +count = 53 +seed = D71729DCBB27D7CB39E9E905025D3E55C8602EFBCC483C9B866EBF82326157833169243C14550AD728BD1470F39C642E +pk = C63CCFC7C0BA0DEFDA9D496A9945355E042274F18BF9B607FA693609B58BCBAAE001071C7916FFE11D517BA54C5FCE7605C7F4BC1588CC1FECF4603F1E67A26BF4FDA95E06640E3CF774E5C13EFDCC21ED11EDB22FB3F503BDAD1938002284C9FF3E6EC928E2B440727E68B88CE804E828A4DE577D626EF6F5D2D6A1174F4CA6C243D46B47BF93780060399530A4685D41D1450399C94654B2E0E2AC1DF7FACDDC78E25BAD03BA413C6545FA427DF909BB1506AB4EB13E0C79F2CF3224869FE5806BB4C5665113DB87251759C1917FD1F3F40BD8C027D4CDF3C140CB6BB6CCF62624B0FF309E9AB19A216B57893F3D4C952B4FFBFE1415901865220CDFE5B42D278F22E0DC858D06499817319C9F016B188489DAD2CF61732F25BBACD99A96BF5CAB58EB2825B7A6100657113B44705C667BD9E48EBFC5EDFD80363A5BEC321D8971CB64FD133E5F7612F2AC7C4B355F5E423F05B64FE135B88CB9A4C3910C3629FAFE612C45517807A91AED59607B05EAEE8C7213E8FA019E7FB2960F221371B6D24CFFEFC714B1686633E68CF19B6E00FD9078007E9E6519D42D4D77DC28A4B9E75632E4265847DF24A365E93173A9F292D5FA4398F320D94C4B14BAC06A1C6F0AEC970C6CF053E7F8C720CFE5D5BB52DC4EFB9415AF80B83314DEA25395F1C4ECFDEE494190FA2017C2FD0ADBE22B47AD7F8DE55EC41E8B7A4B815659F1C11929E03E361B0E813A8EB6CE47FABF9FBC39B513A1C895632AE480BC8A73816CB3BD70F7B9365F7D5995E06E2FC356420407DF56 +sk = CD6A99396EB3539CA663A51E42063A3A262CC1C5A5FCE1566F0597B52AD9FA325A3407F591791A5DB4578B5972093A95BEC3B8E70C1D542C9B5C9789729F89224C20F816F1146AA1493A0CA6BB1E1F02C63CCFC7C0BA0DEFDA9D496A9945355E042274F18BF9B607FA693609B58BCBAAE001071C7916FFE11D517BA54C5FCE7605C7F4BC1588CC1FECF4603F1E67A26BF4FDA95E06640E3CF774E5C13EFDCC21ED11EDB22FB3F503BDAD1938002284C9FF3E6EC928E2B440727E68B88CE804E828A4DE577D626EF6F5D2D6A1174F4CA6C243D46B47BF93780060399530A4685D41D1450399C94654B2E0E2AC1DF7FACDDC78E25BAD03BA413C6545FA427DF909BB1506AB4EB13E0C79F2CF3224869FE5806BB4C5665113DB87251759C1917FD1F3F40BD8C027D4CDF3C140CB6BB6CCF62624B0FF309E9AB19A216B57893F3D4C952B4FFBFE1415901865220CDFE5B42D278F22E0DC858D06499817319C9F016B188489DAD2CF61732F25BBACD99A96BF5CAB58EB2825B7A6100657113B44705C667BD9E48EBFC5EDFD80363A5BEC321D8971CB64FD133E5F7612F2AC7C4B355F5E423F05B64FE135B88CB9A4C3910C3629FAFE612C45517807A91AED59607B05EAEE8C7213E8FA019E7FB2960F221371B6D24CFFEFC714B1686633E68CF19B6E00FD9078007E9E6519D42D4D77DC28A4B9E75632E4265847DF24A365E93173A9F292D5FA4398F320D94C4B14BAC06A1C6F0AEC970C6CF053E7F8C720CFE5D5BB52DC4EFB9415AF80B83314DEA25395F1C4ECFDEE494190FA2017C2FD0ADBE22B47AD7F8DE55EC41E8B7A4B815659F1C11929E03E361B0E813A8EB6CE47FABF9FBC39B513A1C895632AE480BC8A73816CB3BD70F7B9365F7D5995E06E2FC356420407DF56 +ct = 6D5DBED9942D879727D6EE76540F024BD4090082CB4B0BB4F28F469E940CBE52FBC44DC2B16E0274715EB71C132B150ED1AB88DA13507BBF4469524C98E9261D363DBA0C1ED1A86D9642093A875C94DB40812E0ED7FBDB99C0D758D3511D3DBC0E4540267DFCE4F17179ED1EBEE904F77C7993467703291E00039E1FABF3DD3852837B63DBFB0519D597E210EDB8C13BF795A8927F062245D740C521E5E0FC518D8341247AEE37860802D171739B9244081D6F3AFC51EF7C3C532C5DE2C99EEE949F7B7375DFE3D2B5C675B8FE4827C8181F0C6B1D3A7BD5A31ABD448EA30CD3EAC27CA1E11B6ACEBFD4825460ED1F8C01117FEF1EE358C43AD763DE5C8037BDA1F7DC6F302735E0BAEF030A6D63DE20DB8DC12F14CEBE4216540D061007A7812F56607D22A73C0727DD149E70956F4B7AF6261069FFE5C0C68F847C1D2293021EEB23DD64D37DF276B6EBA3972A8BDD69ECBCB94B81AA199C9FF6434BE90EC41D72A525238C26B4E916AC5DF6A4379C0E48D2E417EA7E4CC0298D037EBF1D4464A37332D12354B840C1F7023673FBBBF6A7FBC1D9CFDA31E98FD34A1060762C71E158280AE31E5FCE62FC65AE16033299AE9302693BCBC067C4422E631F7B4B2B5343DAFFC590F5ECA4C82F82C6C4B447526CD1DB28D7F008534D1045E022FDF64C615661BA0DD833889F5717BBA9860134C033014D169CCE2C901AA01777474F538A0796CDE025B63E30FBB0BC1FFB9A0492871F1375F650608F0E9184A747E49DC50C49F56AAFF1A175BCFB19B88F6312933FD9F648D3D921961B94769EB44E6FAE55C83A38573CE243418593A05182E92A3A +ss = AAEE1E32F40266D77EED391768ABCDF3D4232B3752FB153A24FD2810E52397D2 + +count = 54 +seed = A7C2C8EDB3601396BEB2DF0657EC82FD5780A2723581A9E03DEE1CDB018440439BB1142CAB0487C5D136E9AF46338AB7 +pk = 9097AD9405F24E53BE449D3285650E59CE88CF4412468D1D1A4B922EACA855DBAFE948FCFCD35301CE1346AAB3017CA19A01C052FF6A697813F8347C16CB04F7CFC18E44B57E650E3BDE360985EBB10ACFCF4ACD17E9D569E525F05DF32CB882B4AF59A8FD754C90569F5557B47727C9A380BEFD94F2F98F3EF172681F808AC68CF2EAD954AE209E9320E6B228C98D7832BD8326FC49F3056B2AF74A4E01EFB8E131F845347D9CD6A623BBD1857E5721509BDD80DC83A6BE6C8ABF634B71D9DC92687CB8FF94ECF19276B82A1D12F1AB81BDDC361BFE65795F4ED2C31F202D9887B376B61D13BF8D17DB3B8B7AC839925BCB06CE63A030F7EA5556BCB9D2C624DE325577A4478E943C7BB658FD9B5B537B1B9C7CCD3DBD5C38585434CC60C44785AF06B5B660451DEA0DECB5857E26B471DD1960A7E052205D249A41CCB15A42894369EE608BA01C9082BD45206AADC172254AF6DA920BF0E72CF9C7A187CB1D1F19598F254D07277CE1CD319CF8F8B3605FA0BDDFF6400A7FB53524D990B4097252F3610CC34F374641E977304A7AFA008E2B3195656CD4C11D85D716A690FD989879565786D6DD44B61D4103CFE38DAAFCF14D5980BF98083D9CE534B93F6F55B5907EAB7A7D6725B14858C5F3B4D9C83EF4235D4967D28E7144BDA6534E7AB92F82A599AA127226FDE2AA4060A863E9FB46571C5626E79DC3842DB53DED492B990C55EB595788B7438CCAF5E1F87406E37614A3EE8B9891EE26BABBBFFFDC137B456C597D525A8E103B16C99C714D8D7C1244 +sk = 6C8C53ED6F65E6B2E324B84364E10DE42D1C26A106D4D1C99EEE79C78586FB55B9402BF02481CE4B27A52E87FEB92C4399C7F2988D40E942E7496AD15AD2AA8841AC9E53A84C4F6E854A8394306D42019097AD9405F24E53BE449D3285650E59CE88CF4412468D1D1A4B922EACA855DBAFE948FCFCD35301CE1346AAB3017CA19A01C052FF6A697813F8347C16CB04F7CFC18E44B57E650E3BDE360985EBB10ACFCF4ACD17E9D569E525F05DF32CB882B4AF59A8FD754C90569F5557B47727C9A380BEFD94F2F98F3EF172681F808AC68CF2EAD954AE209E9320E6B228C98D7832BD8326FC49F3056B2AF74A4E01EFB8E131F845347D9CD6A623BBD1857E5721509BDD80DC83A6BE6C8ABF634B71D9DC92687CB8FF94ECF19276B82A1D12F1AB81BDDC361BFE65795F4ED2C31F202D9887B376B61D13BF8D17DB3B8B7AC839925BCB06CE63A030F7EA5556BCB9D2C624DE325577A4478E943C7BB658FD9B5B537B1B9C7CCD3DBD5C38585434CC60C44785AF06B5B660451DEA0DECB5857E26B471DD1960A7E052205D249A41CCB15A42894369EE608BA01C9082BD45206AADC172254AF6DA920BF0E72CF9C7A187CB1D1F19598F254D07277CE1CD319CF8F8B3605FA0BDDFF6400A7FB53524D990B4097252F3610CC34F374641E977304A7AFA008E2B3195656CD4C11D85D716A690FD989879565786D6DD44B61D4103CFE38DAAFCF14D5980BF98083D9CE534B93F6F55B5907EAB7A7D6725B14858C5F3B4D9C83EF4235D4967D28E7144BDA6534E7AB92F82A599AA127226FDE2AA4060A863E9FB46571C5626E79DC3842DB53DED492B990C55EB595788B7438CCAF5E1F87406E37614A3EE8B9891EE26BABBBFFFDC137B456C597D525A8E103B16C99C714D8D7C1244 +ct = D41AC91D649A14D23FA853835826FC8A981A530AB0BB19632002FC9546889FE643E05798391BA88B9AE3C8CB21855AA3520AD3ADCE9654ADB9082663A556224D340ABE5B7E767E3BFCB27FC21E68C90545EED0546383B524C89B94BBE322376A3C279C6ADD99F449ED6C88143239E73C0943C6FBFCF8568E3A5AA6AAB462CF6A113AFCCFD33E32B4CED79E5524E00DD1022EA3FFF99C7088E6FB9ED37D273FAEDFAF13A2F452534A19D90949A3A81C30048F8A2A113693D828AF222A07F5659B7129F728A212AF86719DD58AD41B0160BCDFA86864D40A743ED26E963A4C08A20D05858D08465C37F4B430D2649B168EFA0513B3FE9994AAB6DC8B24C941E5F99EC5AD47C4B8418CB4EFB0FBE8ADB10557B7E20C1397BBB4872B52F036FE18B3B5B086E51287F88A03D536B013129F53B3E96D65AF553E6BE0B2C1C8DA0AD850F24B724E30076A7B068303B5AE5248B0B006B5D5A705E5A18956CD6CABEB7DA46D66052D8078A566D7F617C63FC22B331F21C371415F424EDB0F307920F6FB9DB05D81FC2C55D4F3E75A5029EA05F9760B80122B9F6A73702DA53DFFF4359304E465294013562773893AA1AEDC0ECBDB680F673584CAC691621E5A10F76AB4CA02C2335B0984D644C422472F9341A71847BCC5616E6617797F6D8B2B685E308001EDD6FFFD7D3D3060EB83ED8830BAB5787871A0090B0382536853382C353018674AEB9FF2C05C53AE48CFDEE5AFD0BAF0F8AC80B9290F3C96154DB6CB079B8CD1C41D464E28C7A3B731B96F63E7BD76C191A960B79F5602B41C69BC88D2EBEBC8F6A2B586CFB1260BA982D17510884FA14A8D88 +ss = 4853F43FC733C3F60B0A45F127AAA7A7ABD6E2685E492CBFB0D89CB616F3A3FC + +count = 55 +seed = 467F6158CB86B724039FF18C47950AE5C49170163C910FC9A9B30141F86E9C06EBCEC91497BCD156D95758C9F0C6EF91 +pk = 15FB7A9649140074BBE20D49AD24B773F46F44E3EE8021E34EE6C1537434511B8DF27EF3052AC152F333B48B32CD3A9A863B6617126164F27894F239C88CEAC5C603002BA42917573E114351FCD2ACCD8CED0E018DDCAAE8B7367F34DF676738FD5DBDB08E4379092012786806B986087920D58496691196AF9712FBF275B48B9642B0B0A6116AB3F2F3497E031D5AF6AA50A4B7A763C15BD968E20DBA3F8353330D71EA3DBF6ECED48A03EA99CB2304696A4EE20204B9A8BCE1026441955AA672C1CFDA5A997A668E5AC0CCB82FF3551483AA8813D2163772E3F6BFB800D5C6B10FDEA05FDF9FAB23DD7D27B92E40056E7C18A615D0A29C621EDA24AC31B01F43804962221C9E1867668450E7A450A55E1F600285B55E807E3C5DCD59ADC96D02723C2B7305D3A0475E4ACB6F9910ECCE3774B9643B093487477629801BA08BDCCDDAD6204E66625193609443331D1B9C9D7CB8AEF305B4A35644C10B5B2496F2A633C8129DEF8C4B673D1375F66870BB9ADE4C93F67E3AFFDC139ACEA65B73AF5D49A8081986DBE249EDF596E9DCBC4CD9C32EF80ACE11A8C34EF7D6491508D5BF4ACC24BD1F52946DBC048167128986516A68B6F27ADC697D86A34729BAAD98BBDCDDCB8CD33D80B1FEF5B3FF01038E2C43C87245324E3D15F3FD023D3D869590AA205273FBC0ED3727EA5CF19F4FED845D425FA782A9FF73E9D9EBEE002B02DAD086A144C4F0AABD6FBC99AEDD10C83D2D37F6E1CF7129FA05679C32E5FA9D329F91DB414C51B1963E0A4E9104931EDFDC36 +sk = 2107204CD995F1DF14314D5381F8C5440F09A347502E161CFFC0A2EC3DCFBC7324C3DA70FE850E80AA818301D60C70F3038153866DCD5D179E22DB59B8991BB4F9E267712F97DA8BFE5A32BCAFDF920315FB7A9649140074BBE20D49AD24B773F46F44E3EE8021E34EE6C1537434511B8DF27EF3052AC152F333B48B32CD3A9A863B6617126164F27894F239C88CEAC5C603002BA42917573E114351FCD2ACCD8CED0E018DDCAAE8B7367F34DF676738FD5DBDB08E4379092012786806B986087920D58496691196AF9712FBF275B48B9642B0B0A6116AB3F2F3497E031D5AF6AA50A4B7A763C15BD968E20DBA3F8353330D71EA3DBF6ECED48A03EA99CB2304696A4EE20204B9A8BCE1026441955AA672C1CFDA5A997A668E5AC0CCB82FF3551483AA8813D2163772E3F6BFB800D5C6B10FDEA05FDF9FAB23DD7D27B92E40056E7C18A615D0A29C621EDA24AC31B01F43804962221C9E1867668450E7A450A55E1F600285B55E807E3C5DCD59ADC96D02723C2B7305D3A0475E4ACB6F9910ECCE3774B9643B093487477629801BA08BDCCDDAD6204E66625193609443331D1B9C9D7CB8AEF305B4A35644C10B5B2496F2A633C8129DEF8C4B673D1375F66870BB9ADE4C93F67E3AFFDC139ACEA65B73AF5D49A8081986DBE249EDF596E9DCBC4CD9C32EF80ACE11A8C34EF7D6491508D5BF4ACC24BD1F52946DBC048167128986516A68B6F27ADC697D86A34729BAAD98BBDCDDCB8CD33D80B1FEF5B3FF01038E2C43C87245324E3D15F3FD023D3D869590AA205273FBC0ED3727EA5CF19F4FED845D425FA782A9FF73E9D9EBEE002B02DAD086A144C4F0AABD6FBC99AEDD10C83D2D37F6E1CF7129FA05679C32E5FA9D329F91DB414C51B1963E0A4E9104931EDFDC36 +ct = AD6DC098D3843B70817652D1DE6E1C58B868AF65F1BCD11E1BD05A72A047B26AD655CFFA19FAE7B6930F6ABCE65B781C2B5494262EEB51AC09EB9C381246D124905825623000EAD81C890D4FB007C30BEFDAE7436B3A7FBB37527BBDD944832F1F44C327D1787B775A4AA2AC19FE86025AD6C06CAD0868158AB916A4A9C14CDA40B9BFF9ABC943AEB97CEB1CF062EBF81A89C8891E6B30AC015A206D0EAC2000510784D969838F2B1A6453F562E439D97856756CFAE5D002CD9DB73B859B997FA5B8EC9AEB7902B974495F84447E4C1D1218C21C942B39CC87D3E1A927498A43B2CEFD74BE1D45DF6F53C1D1C657A68F1577EDD154B33D89EDC0229482CDEABB796E2EA5B25CC13F3654BE6AA0530D6217DD40FCC2E4F966281ACAD739874F4D274CD11BE31DF811CC45B16B35B881C46E824DB2132F2D0EA4A484BDC671FA217CBC9DF80AA8BCDE64F5FF2F9379ECE900D4AB4AAC7F1B4AC5985B9C4B30DF71C76958BB542D817A7D564D4569E668B676667B6FE1D8606645D3FB46D95DAC76798DB21874D1CE9E1C9BEF9BD1DC373220D08D3B789BC4EE3864CB9158F7F084D4FC1E623003D555903B5DDB8624FC6E1B6A2EB4678D37D5B1585F1C080418DB92D1470651934AD819BA4E4114BAE4C1B7D57500DC3A0DA478A932BE68205B95431BD519A73ED746E984634DE656F190E7D31F3293F79AD5661D114144BC373EC5384B1AAE61ED63BB74AE099868E00BD529875D7FAF22819EE4ADAD1E68254D856EC5D6751574A1488B5AE54D40815D565A9B55AB7725335187ABB0F674AED93D659BDF2683F7819BDBBD6BD758695FE0BEF4D4 +ss = 8C5FA3CE335959851C3C06CAFD39CDB9E1848E8D4F72128FD9842AB5BF244F17 + +count = 56 +seed = 687C02DE1041ABAC7B2C1E6EC2A7C3375552ED5EDB10E3A8139C24CC76BDA44D719D8121A81D47A0B762B4E9EEB85235 +pk = 918C0A876E1A5E33AFF35BEA957DA287F4EDC3BE5997ECAABD3B7E09EF31F9B3AB97E7057E5D79C4DE344634103E64F2FB3B49A5CD12E7412CDAA81D6429FCF1B532B1EA090B9E7625CBCABF6628B834709263814406826D109B4815851B916D253D3F736EF09DF7B1FC8C75B566D0A6E306FB4EEF2F382985E88FDB5C40FB9B8A0830FC2A11E1B49097475ACA1E681A3CAB5A434D3CDA9172F2499D05916C557232187CD0F5784ECE1259A01539F5EAF27362F0BAE56DAFB466773D5A58CDD449D66AB0EEAB5D66234A291251FB3526F1803DF153D957BA3E004551965B741BF5B180E2E622B740FA0F2356EB48A7BF12413D8C3B8A5080E43068A875F5078341FDFB5A88D48D19F9C4CECA06C20DB8AB31430423C639A7FA3104224E02D856779C46E9BB39F0CA737DB6CD92C0E1B90868157BEDF7A2606888774B63F29C7957288529895BA51157DA30BB73FB1009AD67405F626A097C114519A4FEE76FFDBF109FB6FF1E151884F199BAA4F6011696BC4A0FDBF833507A33B9CFC2C4CDB8BAF8F602640C89F731EC88E81D1F529CDE9A841F7BB4F804EE7C9EB8C46A86F5AE26BC6D1A4A0F545CF64199EC6971358C9AFEA036AC9FFE65B6D62557BE8B3D968983F138A201C6BA12D1D3B19775B8ED8773E05C0D4084D64B0E918195BAE4C90F1DF9B271C64F0A93796FF1559DFD7B0624A9475D5BF811055BFCE411A7B8B43095BA99E244021B2148144C3F0521138DA5135371685A3686BD9234D4AB338C49DBF4C5B5EF036DB4AD69CB941B2F41F45F6D +sk = 63A925685A8AC5BBD918FAA33AC397D1FFBCF99135D9DA7C3D6FF7AA4C50AF3D3AFDB8A246A56EE71465591831C371F2EB87467B0559DEDD776BA063EE6D2F93057CAD9DD9E0AEC1A30AE1A0635DF901918C0A876E1A5E33AFF35BEA957DA287F4EDC3BE5997ECAABD3B7E09EF31F9B3AB97E7057E5D79C4DE344634103E64F2FB3B49A5CD12E7412CDAA81D6429FCF1B532B1EA090B9E7625CBCABF6628B834709263814406826D109B4815851B916D253D3F736EF09DF7B1FC8C75B566D0A6E306FB4EEF2F382985E88FDB5C40FB9B8A0830FC2A11E1B49097475ACA1E681A3CAB5A434D3CDA9172F2499D05916C557232187CD0F5784ECE1259A01539F5EAF27362F0BAE56DAFB466773D5A58CDD449D66AB0EEAB5D66234A291251FB3526F1803DF153D957BA3E004551965B741BF5B180E2E622B740FA0F2356EB48A7BF12413D8C3B8A5080E43068A875F5078341FDFB5A88D48D19F9C4CECA06C20DB8AB31430423C639A7FA3104224E02D856779C46E9BB39F0CA737DB6CD92C0E1B90868157BEDF7A2606888774B63F29C7957288529895BA51157DA30BB73FB1009AD67405F626A097C114519A4FEE76FFDBF109FB6FF1E151884F199BAA4F6011696BC4A0FDBF833507A33B9CFC2C4CDB8BAF8F602640C89F731EC88E81D1F529CDE9A841F7BB4F804EE7C9EB8C46A86F5AE26BC6D1A4A0F545CF64199EC6971358C9AFEA036AC9FFE65B6D62557BE8B3D968983F138A201C6BA12D1D3B19775B8ED8773E05C0D4084D64B0E918195BAE4C90F1DF9B271C64F0A93796FF1559DFD7B0624A9475D5BF811055BFCE411A7B8B43095BA99E244021B2148144C3F0521138DA5135371685A3686BD9234D4AB338C49DBF4C5B5EF036DB4AD69CB941B2F41F45F6D +ct = 338D6BFA67711475C079D309D028695A10DA0946EEF0D62F748C1F44578BF085D02C1C0C2F972251480362909B1C10A3999A31698EB841E63C4EAF6E1DD5C6E16ECB094F5643036217F5F3B8A9BEA639F4C980C6A4AFF99EAA0BED650F139873FABCBDC182ACD0209092CABBC19A7D60EED0F305496F0C5546CE9DD4C19DA8D9D20001229BCA858FAB7D76F1E4785EA33765057D3756B5CC49C2EBBF7FE5C4E4541FE18D947993BC9DF109B694E024A50630C99FDC4BE3E48CA45B02C3090F6901AD996C2930470F40D0082187431F7AC6196243FF8D9C4A01F4E2A5C826B539A186EE90D3D0171F883B209093EAA5675323158F2740FB6E3C02E5DF928AA0CB1FAE0717D2A7197B3A3479FB72D1A2D29D3E1CA60752C6B0DC26069B7D9508B6463BD64C42B2D783251D2BF7CE7D4E272380713EB3702A088E4FF96D35AC97379E63AB99E4531BE6DFAF7635149BC03781E34570663E892A5C0375B38F6DDF9AC8BD023DABEAC9E5853F18139AB81477E18E2B8BC520AA1AEF502755031FD67DCEC1A5E1364B71C454BFA26BBD383E6CA2494FF00AF97950255BEC5AAA1F6A8D45F2A1FC64B2768ACE9A87312545A939A8EE8EEBDAA4C6CD534C49C8F862003B592C4D58B7188EDD8D6C719544BF817D439010FF413EA0E6ED94A9BC08C2F655EADDB37CDDF57AB8AE771BA0EFAB7C23CCA8CF6C507EB5665057BFE60BB79E5BF3636638B06E46DA782782D881279361320AE0F96EAEF183487A99F604CC883A8D4C4571479E5C93729206213059FD5D4EF8245A4DC45767708940A3B0331353F3F3B44CB32EB4EAA2F0F7ED30723DD21461B00B +ss = D41874A2E197464EEFE132987F3B7D48B102D828D9783F66FD0D38E84BD323A3 + +count = 57 +seed = 4142237070C216BCBE245A39BD9220533C97651D84832B26727855AD994A0760C52B9319AD404693E4248B8C5FF324B3 +pk = AF164FD987430A7901D7896A23A68E506844813955D965761C1DA2BE415C039B497753E5FC91CEBD75956708A4AD9DBB90B62E157DC0A965CC350A523C01F2A2CF53E5C5677E792BD7E2DAE32A83D329779DB1E5ACE7BBEE7C3C272C214DFAC2D9AF2472F82981B525128E48523207D9B62220B89623BC8206BC21F5A3AC2F406988B402E3E187A11E689143D45A4D405BA00C760ACC0D7FED7807479A84FD781C385AED31AA100ACF88F9EB79737C43D9B6F78BEF6F897425A4AD6A8CD55FB6B68E6199581C9E9F601829FFDF9DBBFD7245C713EA9B6AFD5DE268A21CEC23140C6418F3B29EE7B9BA388BD97D0DC2A31DC191EEDD09FCBEBBCC2F5972A20369BCB7E86DDE8842A5B745CDBE0F3481CD0C5225989D2F8CF6BE261F5DACB1ECA74E2F777C2654AA0F45EEB2CBB51C739D1E30D60233C3E68F97970ECEFD7B1959903191D53FA218E07582B0D36F3888F1FAF700F885659690B120F1CD211F90E03C1CBACCA3362AB6073C9857397541785DD16C2B467831339D4ACB8A913776D0D6E81EA6910E007D532FDDC4C41B6AEEBACA86694E53B4F1EAFF28883C22D5C6F72714F24EFD55DF7034B6D64C83027791AE32375CF54A21D366E783B2ECD7120B9B85C84D8396EE5FE1DF376820C34069A9B3D43A6665ED8AACB4D5E2E48A0FA32B8AF2EAE4574650828C541BAED27F6315836A2CBC3C0442B19F64012542A6ACE9FB98CB6A18B49E56AD7A692340D0D3D60799C406E8E5473A43893C0D23A7CEDD99FEAEDAB114B6B372E6794AF6FD7CAD6A1E +sk = 6A1AEE5E708C1B47F02BDACCE4F56C860F74FC7CFEC1EF3B58285B1C8AD7FEC2230E05B7114FF0395CC6634DB1EAE8258072D09C09F291E92D6620B177DC50D7B992373F9086C7AFDBF4B44A96BBA802AF164FD987430A7901D7896A23A68E506844813955D965761C1DA2BE415C039B497753E5FC91CEBD75956708A4AD9DBB90B62E157DC0A965CC350A523C01F2A2CF53E5C5677E792BD7E2DAE32A83D329779DB1E5ACE7BBEE7C3C272C214DFAC2D9AF2472F82981B525128E48523207D9B62220B89623BC8206BC21F5A3AC2F406988B402E3E187A11E689143D45A4D405BA00C760ACC0D7FED7807479A84FD781C385AED31AA100ACF88F9EB79737C43D9B6F78BEF6F897425A4AD6A8CD55FB6B68E6199581C9E9F601829FFDF9DBBFD7245C713EA9B6AFD5DE268A21CEC23140C6418F3B29EE7B9BA388BD97D0DC2A31DC191EEDD09FCBEBBCC2F5972A20369BCB7E86DDE8842A5B745CDBE0F3481CD0C5225989D2F8CF6BE261F5DACB1ECA74E2F777C2654AA0F45EEB2CBB51C739D1E30D60233C3E68F97970ECEFD7B1959903191D53FA218E07582B0D36F3888F1FAF700F885659690B120F1CD211F90E03C1CBACCA3362AB6073C9857397541785DD16C2B467831339D4ACB8A913776D0D6E81EA6910E007D532FDDC4C41B6AEEBACA86694E53B4F1EAFF28883C22D5C6F72714F24EFD55DF7034B6D64C83027791AE32375CF54A21D366E783B2ECD7120B9B85C84D8396EE5FE1DF376820C34069A9B3D43A6665ED8AACB4D5E2E48A0FA32B8AF2EAE4574650828C541BAED27F6315836A2CBC3C0442B19F64012542A6ACE9FB98CB6A18B49E56AD7A692340D0D3D60799C406E8E5473A43893C0D23A7CEDD99FEAEDAB114B6B372E6794AF6FD7CAD6A1E +ct = 5F3CAC0BDBD5EE7E506D5148E72805F405438AF828EB9EC86FE8900FD895A1314821A7394EC7D957AD249BBA93065D8D54EAD6D1645E38B7FFC7A1BD9ABF759725E1C8A821C758F5DB8B84A2134DE904DC9825D70EBEA539410CD6538A5EC4DF525C0847517278346426AE7A8A815CF55C31D677E0530D9AFB2A7E288FD21F995E1BA8F9DDC11E420F34DC6A10D99C2CCD20814B1397E1D8725EB8445D2413C5B8CF4611F7FB35FCB85456F415DC02EA994459BB9C0525EC14D9101ADAE171C8C88F45AD6A5A5AE8BC57C80ADAA0BB56FEEDC65A82E274C4036D2339DFB25C87982F94507E017D0F4E00EAE9072E2DFB842B84F8642EEA2B4016584AD54822C5CDC6E612365287079051ED61881DD780574430985B0F22AA7307DC43DB5D41B647E5E8BB1571AB7EB45C3A866232EE36B5D61911A74604BB0DA87527F6B05FEF821F791AD814B68E7E8F1F1D5982F746C46177ACD51903CE888FDBBA2EC6A7FFBE1A79843A4658BBEFC0818558AD199AA82C995E8FAB6B3200FBA5E5D61DADA95646E880742DA93FF91CC3E7184D972F823F338F70608C738C1AFAEC2CC410F0C12FAEF7510A28253DC99DBD2DF69B125D39BFE0255059D15B6A02B920BBD75E3453A309C5B22C7143363DDE27D48ED37A879CFA8E0CA5C34B13943E6022E6C747F11818BD74DD5D376BD0B650C1BEA56E0E163D80A384AB3424FE0AC0A107BC7652D6091877E97A82ED384FA2F58700C02D04F525EF4AC354CC08AC74B1E3A03E5B433A29CAC4E64E5B1D4915D82FA6DA5BFC4CDFFED0F8C0B5890DCC2476C71C1FCCCCBB27E16A42DCC1B9662CC21FB3CA5961 +ss = 160593FEC401B6BE109A262AF3CD83B1DB8EBBDFBE7773EE40F8AE6E9399FDBB + +count = 58 +seed = BD334D7B7EB14E00E68863F2E5551A095F8AF10681C28353FD19B9A7E70B8BFE266840860609008A567ABC66316C77CE +pk = C2B5E729F4F5AC62CC826F5BDE38BECE48E510EBCA1B9279EE150DF0F24463A8BC211F716C5BA7683BEEE5B05B5A6590858435892E222B8176D2C1BCB09837E2261630C31C0E4A9EAD090AF29EC2F1E923113E4B51AD0161244795A3A7478726F57F691BB2D272BC4ABA057E0DF5BD6516A6BAABB412FF061E77AD20D94C89FB345F04ECD39E0C950C1302AD78ECD7AB26436AF579DE5EE3BC28C8CA53302AE399CD79F978F25A2DF91238360B3CD74BF39B21167C60316B20A28718295D27F9804301793D04973BDDF1233493044D2D9FE4930DF8265E703A822CFB64629FD545A4DA7C7C69BB8BB8C4E5D2F68597992BBD8C208EEA9A9314A692EE0DB320A59FD24C214F0C8ADA8B12A6265B82B0A0CF06D1D84B825BDF6533AA957E6227FF54B79E12B3ED469333C708B3250AECCE92F80CED3FAA43720E99DFAEC9CC14A193D4863D415A01E35A9ED061C3A28F9F2E52CD35BF45289527470D7147987D6CC4934B3B8413827AE2654A1DA988231837DE5693087D374148C339B5F275C19F21A5435C5D56AD89A2A398428D66FD665CB2F1B046F7922F305B85B0492A3FD3140F89DCCC4624A897E8595FBA498BE2B9D56B673DAC94597B4430A1E946B156E2E1811E2E563AB1E4CBB912EE502C8EB54E3CFAD23AA146B29B79CE8F0013DBDA67E444AF3B399DAEA6FA346BBAEA8B4C69422C024DC619A266D7D825EC7DDF1AB8CE745F776A7C64DB539CC05897481C81945F7F351D3FE57862F5857DEF9B26180535AF58E1D41CD5236E7DC963556A675969 +sk = 6396B328B100E4C7F4BCAE69875EDEA1A1982421558C608C13C592BF7B5D0FEF1100CED48ADD211A5C937B8D6079D8E271AF3F949EDC61F70E60453AEF20DEA99D44DCF0E06FE406A8484BD3CDF02401C2B5E729F4F5AC62CC826F5BDE38BECE48E510EBCA1B9279EE150DF0F24463A8BC211F716C5BA7683BEEE5B05B5A6590858435892E222B8176D2C1BCB09837E2261630C31C0E4A9EAD090AF29EC2F1E923113E4B51AD0161244795A3A7478726F57F691BB2D272BC4ABA057E0DF5BD6516A6BAABB412FF061E77AD20D94C89FB345F04ECD39E0C950C1302AD78ECD7AB26436AF579DE5EE3BC28C8CA53302AE399CD79F978F25A2DF91238360B3CD74BF39B21167C60316B20A28718295D27F9804301793D04973BDDF1233493044D2D9FE4930DF8265E703A822CFB64629FD545A4DA7C7C69BB8BB8C4E5D2F68597992BBD8C208EEA9A9314A692EE0DB320A59FD24C214F0C8ADA8B12A6265B82B0A0CF06D1D84B825BDF6533AA957E6227FF54B79E12B3ED469333C708B3250AECCE92F80CED3FAA43720E99DFAEC9CC14A193D4863D415A01E35A9ED061C3A28F9F2E52CD35BF45289527470D7147987D6CC4934B3B8413827AE2654A1DA988231837DE5693087D374148C339B5F275C19F21A5435C5D56AD89A2A398428D66FD665CB2F1B046F7922F305B85B0492A3FD3140F89DCCC4624A897E8595FBA498BE2B9D56B673DAC94597B4430A1E946B156E2E1811E2E563AB1E4CBB912EE502C8EB54E3CFAD23AA146B29B79CE8F0013DBDA67E444AF3B399DAEA6FA346BBAEA8B4C69422C024DC619A266D7D825EC7DDF1AB8CE745F776A7C64DB539CC05897481C81945F7F351D3FE57862F5857DEF9B26180535AF58E1D41CD5236E7DC963556A675969 +ct = 91E34F38716BB125C943A4F754B07D60AB701817329C1C95F9767B56E2565FB8DB657F4C168EDE33052B34823269EB3B2254ABA379FCD5937A062C845D5C812964AA509F76E477A2CAF20D8D8A65B5782441963720EBD714C701D103725D1A1D75ADD940C8B25CF1BB6B739B95F0F2AED761614D650F535403CB0A58F1A9434D06470F95BE068D9B81188322B17EC37C59D02E0F9EA4002E965BF2BD1E8C48984B8450F81670DC1AD8A9DE576AE39FFA2DBA342094BC14B990DDB76AA2C4B94EEF044D2D3228E79C200E24687743E5391BF6A3A464C3BD084AC32D3A2F84C9DD14F19B67C8784640F6E535582F3A65D7876AA3BDCE726B4B2145B595471FD9B857B063F993CD23D095C1214F67690AA9B4BD59BC31F923477423D169D19C7B998D39A29ABA6C4395FBACE4FEFF79950EA93E43F541920D05414034B14E75484F6696A2754088BB72E5F89303CE89E4B04DCB0AD2102ACC9C70F7D52FE057FC82C0F699CE7035B74533D8477F816D477C3120D30CF1078D54C8964364D14A6162E1E5D39C32501C96F26EC3F0DF80DDBD44DD5EEB16A28519FE3CAED37EE2ECBED6E8AC1E282CA8542D60905F141D757F00703E9FBCDBDB4E9239D309B28DEEAD7F8C69D32AE7CEED776E71FF9010D236CB9490BD701BFD96ABA59F1AE77A7B7C6B6839D1E296A962736ADF0E73A32A4F339EDB5C640243AA7EA6549B1E7A66929E42EE62DAF0828CB172F86CA5E5185656666606ECD313C1187100EF600AA3176BD6E9085BC4B32518E184459EF7DA266D46471CC7ACBECB3F0FEE8660FE4992BC61D5DB495913850B805CA15AE9D5211D3135EB +ss = DDAEBC31AA82FECEE4CF6364556A5D79986BD2BEFFFC519CF1AEDDDB26A04915 + +count = 59 +seed = A0264C58AB1F2CBCB212077FD378D340307ACCB31F1312137CF84E3D3135044D4EAE8BD38BC3E540A0C14D46458F6179 +pk = F2CD33D0403CC1FE95410E1E9312CC7B2601ACB189BF030DADA92A539016451D574EF10F336480F29D31403F863CE4BC69FBC915BDB8A1766C0BE74B61DCC2D57D6F79541096E12A1D14DACF5D45098BA3CEE8739355B5084F9BE5FA273E6ADF284FDDD5A7D3FCBE00105441ACCEB1AC821B77156A8479B15087332989BAD6EE4FCBF3DB10E3C690B8797467DD715F0AF1CB98AED9F5EB1AA35DA482C4DD9C9095EB96BDBCF6900C54466C5B29316B06B91B64725CB6AD6F1A56253088C182909246CBD4EEA14623DD1E76E827E7A86A71A4CAABE2CC10C65455539F3E47778C48038FD98FF23ED294EFBA9148D3CD189AD5387922E16C3779B16FD482F8B015ACF7730176C0480859EE10D0E51EB8EDD9F8BE3746841CA02C2D81591E08434FD99CE87EC0E41B81CEECF9DAE3752B819185672DC6DC844F8B64B76B9EEB61EF012017BC379D3A7061B23F54388AAAC75050694CA7375B18A4E6A18E213C7AAC8FB0BC3A8C46805E18D362A793724E47CFFFBD9C8814E34D1057A0031074D475D44D05653BE73D937CB024D958A57903B588FD82184FA97C04FF6999EC7F84E871B4BCC839E4CE42D2B2AE9E3239A0C5F8BDF230ACD82B3044394BF67AC3CF124695A4EBAC4C8AECDD850766317838FAFB5BBCA0C4258ED985A79B49E42CDEC7CE08CB503A8EFA7E2B598A955CF1C50D2A1FB339BB30187D6450C3A98A3DBD8D2C721F200FB616AD3672E83BE1C66600630FEC9E903E1E56AC88937FF968C858A6878FDB998F2C61DE6C8E50A784257ED9351E42 +sk = A453BCACDD2B0D4646009E5ED451C3C45F08FB827EF733DB3C517A9DC1AF93E67A3CC8AA3239D4C52CE4C95AFDEFF6EFBFACAC10D294EDC0E7CF4535059BFDBABFF7698FF728119CEFE3FA1A6BB2F800F2CD33D0403CC1FE95410E1E9312CC7B2601ACB189BF030DADA92A539016451D574EF10F336480F29D31403F863CE4BC69FBC915BDB8A1766C0BE74B61DCC2D57D6F79541096E12A1D14DACF5D45098BA3CEE8739355B5084F9BE5FA273E6ADF284FDDD5A7D3FCBE00105441ACCEB1AC821B77156A8479B15087332989BAD6EE4FCBF3DB10E3C690B8797467DD715F0AF1CB98AED9F5EB1AA35DA482C4DD9C9095EB96BDBCF6900C54466C5B29316B06B91B64725CB6AD6F1A56253088C182909246CBD4EEA14623DD1E76E827E7A86A71A4CAABE2CC10C65455539F3E47778C48038FD98FF23ED294EFBA9148D3CD189AD5387922E16C3779B16FD482F8B015ACF7730176C0480859EE10D0E51EB8EDD9F8BE3746841CA02C2D81591E08434FD99CE87EC0E41B81CEECF9DAE3752B819185672DC6DC844F8B64B76B9EEB61EF012017BC379D3A7061B23F54388AAAC75050694CA7375B18A4E6A18E213C7AAC8FB0BC3A8C46805E18D362A793724E47CFFFBD9C8814E34D1057A0031074D475D44D05653BE73D937CB024D958A57903B588FD82184FA97C04FF6999EC7F84E871B4BCC839E4CE42D2B2AE9E3239A0C5F8BDF230ACD82B3044394BF67AC3CF124695A4EBAC4C8AECDD850766317838FAFB5BBCA0C4258ED985A79B49E42CDEC7CE08CB503A8EFA7E2B598A955CF1C50D2A1FB339BB30187D6450C3A98A3DBD8D2C721F200FB616AD3672E83BE1C66600630FEC9E903E1E56AC88937FF968C858A6878FDB998F2C61DE6C8E50A784257ED9351E42 +ct = 95CD43927ADF2AC396944353EC5C55CB051567663D51495907CCE98E79B55D67A7FCA9663EACED7CDAE0035BFE4FB9BE17A9DA0F3A8E2CA39D0361D87BA449B33B2364E1BE0C4F0EE223DE899DB5BFEAA4D4E8AEAC4F696B672304A10A5EA5BE25C7D5D2B05E7F98BA6E2D3E2969F888CADB6111F7598B9A067D656E669500CEB47EEAB89CC04DD40C10EF9261A7D96E2881E3339ADD464787E925FA413AC4FDBA267ADBDD5F9ADB32C1B94370730D4B1E03EDC3AB5DCD9E0366B0328D043B7261AA487A4F6F9041AFF0608392115CCE46F856C374B56171C2352F894CD8BC576690E933BBD423382F5A82FF015AD38D30C3F8C5D94139467BE7679A54B125C0ACC3C6390D29C191B40A40A7C12BF9030BC613CBE33F14B6961B3BE8F383631BF2A7A08B6ED8041915175E610CDFA57466E20230A811CE236DA3B4571AE9850BAC7FB5B997330DA6B5D40A673909338CD076083594970C44609C18ACB44263621BD29344C7FB26C341CDA0AC33BE0247C8B3A448355087199D8752520F14C6D9E643B00441B455B64ADAE795D14CC5BBC449EBAFC17893FDE00B637F084C5D0004D65C111C595D01D2095FE6C8B27AADA2D233166B8E043CDBB1350832D0AF24EC8A3C8AAD24FDFE55FC5AAF44E57AC8E05D87F7113E23C365261BF11D36456F076F9B75916A1CC6A01A6C693F74724E1886D8EF1BF10F1DD0B3A128BB1EF3F4B6C2A7B47E4482A136B241A956C60F696FA9EC02671629B75F75BE07336A5B1792FE20C007783F7CE85B363B9A7806CA2F57CC2AB43707776689F1168C4848982512716315C6091739C932C55E6F2551959763BD +ss = E2EFF280E3820BAAF517F9B5C328FDD24447D83950CC4FB37FFE57DC20AD10BE + +count = 60 +seed = 99A9CDBFC674AB3FF2C64CDED7D697A6E27A767434A47AFF7C3FBF3C6A22D6043D27868955286A13EFE3DE36D22EC48E +pk = 13BA81DE657B77787E2CA95BA07A62D47F2031374C794E0D48A4CE4BD4B90F5C5123A6740A8693E14AD506BCEEE50174C7E398EC04B47B7820C0EB43C254681B33DA5579878FE782295C5809942567027E6B300B60D5D4AD2EBBAB63D509821E364DBE3FFBBDA09EFABA2D7B841F69EA8BE96238E7AFA44C6A4B4B10811027E3EE74416D78C4F694B7FA64CE965910BAFC5769C517CB7E98843B20CB716ED6D87E06BC47F8D5ABBDD90C2EF911869DD9DAD5C2C86AD50A9EA0086E1E7ABE853ED2FD1F8247D8F6A7B8CE08A69803C8AA7F3509AC43488C442339F673BB287937928A02AE1194D236C173E479C4441BFB2C0E5DA64A658ED6770C87974341C2FD25F7277B6E174050DF7FBA5DA57266BF315AFEDBDD7381D90A29EC1C0BBCB7858F0CCFECCD9D2B4C6C032B74D11E99571A54F24D02F5760E506517203541146457FCD043B963A91239CB6783595C2FCF417CE31816B6AEB1460A98428C8340BC06A32DB0B72BE0E678125FA67FD1EB28F7FBF58499BF16671430E69B9F018C7508AD90BBF3F168235CE9EF8EA35F7AE21F605BE21415496F0EBBF179AF4915CAEEEC8AA334D2C173AD5512BC20704C42AB8FB99CA3D5239D74AD362C4A46B8B270F0980F8DA3F500D41F39D8BC984D5711AE7500156EBC375C6E269282423BDEC9AFDC4ACD7377E998E517A7E750E25A74592B57EFD614268FCB143553F7E72C21E5E655420838F62B1CA0FA0B6DEF783A7577BECD0C38DB4898868D8DAFC74CF331E25E0D243306F853A8DF112B371D905A8E12 +sk = 47CA2B77C5B717F423222C2730CA5CB9C856BC951D01B2B2C80BD76CCB5539B78F1481D7CAB000E33FA07DE8DC9627A85E76FABB4428A3376E66300CF12A07870991F8D8905ED1F967B747102EDA980213BA81DE657B77787E2CA95BA07A62D47F2031374C794E0D48A4CE4BD4B90F5C5123A6740A8693E14AD506BCEEE50174C7E398EC04B47B7820C0EB43C254681B33DA5579878FE782295C5809942567027E6B300B60D5D4AD2EBBAB63D509821E364DBE3FFBBDA09EFABA2D7B841F69EA8BE96238E7AFA44C6A4B4B10811027E3EE74416D78C4F694B7FA64CE965910BAFC5769C517CB7E98843B20CB716ED6D87E06BC47F8D5ABBDD90C2EF911869DD9DAD5C2C86AD50A9EA0086E1E7ABE853ED2FD1F8247D8F6A7B8CE08A69803C8AA7F3509AC43488C442339F673BB287937928A02AE1194D236C173E479C4441BFB2C0E5DA64A658ED6770C87974341C2FD25F7277B6E174050DF7FBA5DA57266BF315AFEDBDD7381D90A29EC1C0BBCB7858F0CCFECCD9D2B4C6C032B74D11E99571A54F24D02F5760E506517203541146457FCD043B963A91239CB6783595C2FCF417CE31816B6AEB1460A98428C8340BC06A32DB0B72BE0E678125FA67FD1EB28F7FBF58499BF16671430E69B9F018C7508AD90BBF3F168235CE9EF8EA35F7AE21F605BE21415496F0EBBF179AF4915CAEEEC8AA334D2C173AD5512BC20704C42AB8FB99CA3D5239D74AD362C4A46B8B270F0980F8DA3F500D41F39D8BC984D5711AE7500156EBC375C6E269282423BDEC9AFDC4ACD7377E998E517A7E750E25A74592B57EFD614268FCB143553F7E72C21E5E655420838F62B1CA0FA0B6DEF783A7577BECD0C38DB4898868D8DAFC74CF331E25E0D243306F853A8DF112B371D905A8E12 +ct = 7C170687D96BFA69D9EEF29E9B8281612BA3D1E7A5A7E33D75ADD0CDF28AA7062EBB8D27A272C93388E30E1CBE4069E78741CAB8F195B5A6F6FE4C4456F281031121327D02CDF7D7D61B29C31AB772B46C26E1B1172A5B99C7B9770C8064BE52802EC4D073B918DC4A1B0D83886C79A1EC6E51ABCD8697A41453E1C8955775A7312B6DAF0A7418D4BF62DAEFFDB924C7239D503E5BF663A98A88FAAAAFA581DA2A0C42BF446CC8442AFD60B91ECC427036B80C5313265C62658A003DC15DCC205EC7FCB439775CF81E6E1A398C5F5E9A50B9A321B702E3600F791D9CA03747E4EA55DC02962C0FE991DB93D1D25D0FB15418FEE1721EBFCC76275107EBD5F9084A3ECA34672D83FD28997933F664A8E6EB1325A57EFC83A9882A437EE9C99FDA15C2B5BFF792D0B312F0FE3613020BA8DA026496E3129DF3386F509CC5EE7074B152BE11DB6E6E828624C00DFB3A7CDAD92AC284812F8852FA52385B70DB3DFB96664C8CB385A0F3EEEF353802E6EB91FEEA511345D31B4B272A3940A3CD3EA763E70D6C181FEEC41CA0BF308C2115EA4A13CADD1694A228593D9E42709B55A5EA872F572CEB32D0868CF3E8EF3A9DF679B330CB6C01CA8BEE117234A5AE353E314DDE809A36001C0C9E9D582FF26AE05C170A6946680B5E617EA77229E97ACFF1ECB5C134B2DC4476A6C8F2DD9BFBCFBC8D590A798AE21FA3C993B19FF237792683D483FEB0CA1DF3984309D5EFC0C555385ADF5DA0D6140FB5070157E99AC108ED14B27CE99D355B731F8A8D438A07BA629442C082CF640CAC1FD1515246912C87F1A547AE5F628C952BD6262E1FCB4B31C54E +ss = BC6C4B7FB37F8074CED5D09537104E7D2F8A25020E28E13D63D86E9A5619C784 + +count = 61 +seed = C799D57B41F28C5C446DFC58A5AC6499C4BCF3C162AFD2B09A16549826EC2A6F689E44BAFC4ACC82F5D6AEC23F4A3993 +pk = 5EEA261754615A059832CE5D932A39BC7E4B992B90A1CAB083941DE1E38ACAED153BA01093133397AFF88B981B7870D7EF0D0CDC9A69FC785FA72F58201C1886BB949DE7690939828E80EBEA68CA3D8E4F3F2A1A1A829C4AB5F5760CA6528566BE74681B856A7A854F93361A2A1D29B041167B311AF4F9E4BEABDA32A02C6FF1CC39C7ADCA78B9671321F656451AC5D9BECA61D4FB829CADDEB76F2E7D04C9EFD0901DE8AE3CA4FC797B1562DE2D0B10F8D9CF8A27997A4E4F8D230836C3DEF43839056FFE69235BECF753D6ED444D01BA88CBCBE910F449CA61A0297CBA2B0068236DF15913A96A6D1CD82D45B0B6B96C0BD176C9838706E13C8973C534C96EB0A7EC0CB1542042F2B9143DFE6ACEC82C850CB55C905AB2F73AEC8B761AB8DDCF244200ED18CB6EEB5D1A052827E3FB4FD4BBF4A58FCF4AB431BC2BA1D88E9117262296EC512BE045B2F2768E3393923C2020BB1C256232062DCC1F0E8C2A937F1B7F5275D466526AB06A878E92D68DC7F716075613620DBA137D6EE1714718B374167FD6382EF01346A209CEAF967EA3133C1C8331B5C9E6B10A465ED1400A1F7BDF608CFC188E1702DCFB0AC0E53BE22E983AEBC36B11472D09AFB7B19BBE48DE50BB50C4D9D0E8CC18616E3A46A4D5B6B924CC019426C70DE047AF0D165777228C7B18BB1A068A0557EA3F307505022D5FCBBBA2F37DFA08FD4F4406A3CF69B833726CF6808BBB0F7310BC1DE97CC01A75C9CF4791255A6EF457990630C44F6DB5EEBE6CA70F0EB45BC282B51C6891C43B1E +sk = AAF6EB40E596A5E3E8218871E708B089240DCBE7FD3641F0E5E41E071CE49107E2F8D320AC3CB0C52EFDC753282F092BC39BAF4A18783A48EA031A191865EB7885D03687DE2B06E1A480949CC3D986005EEA261754615A059832CE5D932A39BC7E4B992B90A1CAB083941DE1E38ACAED153BA01093133397AFF88B981B7870D7EF0D0CDC9A69FC785FA72F58201C1886BB949DE7690939828E80EBEA68CA3D8E4F3F2A1A1A829C4AB5F5760CA6528566BE74681B856A7A854F93361A2A1D29B041167B311AF4F9E4BEABDA32A02C6FF1CC39C7ADCA78B9671321F656451AC5D9BECA61D4FB829CADDEB76F2E7D04C9EFD0901DE8AE3CA4FC797B1562DE2D0B10F8D9CF8A27997A4E4F8D230836C3DEF43839056FFE69235BECF753D6ED444D01BA88CBCBE910F449CA61A0297CBA2B0068236DF15913A96A6D1CD82D45B0B6B96C0BD176C9838706E13C8973C534C96EB0A7EC0CB1542042F2B9143DFE6ACEC82C850CB55C905AB2F73AEC8B761AB8DDCF244200ED18CB6EEB5D1A052827E3FB4FD4BBF4A58FCF4AB431BC2BA1D88E9117262296EC512BE045B2F2768E3393923C2020BB1C256232062DCC1F0E8C2A937F1B7F5275D466526AB06A878E92D68DC7F716075613620DBA137D6EE1714718B374167FD6382EF01346A209CEAF967EA3133C1C8331B5C9E6B10A465ED1400A1F7BDF608CFC188E1702DCFB0AC0E53BE22E983AEBC36B11472D09AFB7B19BBE48DE50BB50C4D9D0E8CC18616E3A46A4D5B6B924CC019426C70DE047AF0D165777228C7B18BB1A068A0557EA3F307505022D5FCBBBA2F37DFA08FD4F4406A3CF69B833726CF6808BBB0F7310BC1DE97CC01A75C9CF4791255A6EF457990630C44F6DB5EEBE6CA70F0EB45BC282B51C6891C43B1E +ct = 0ACCF97C1A2AD0EBCBD00B1FAFA60AC76ABF5165EBFFB6D5B5BD5CC5F481F153E917383B8DD08C1ACDA5FF2471357B0C6EE67A32AC00D16A8A7ABA2EE590EC6553F70CDDF6E61F95FDB88846E64AF4722F2A868065957A06C84891F9E3011B1168244EA46D2463788453AB79B819547704A3099DB704A075635594585F4F27A91CC5063D5E66C7D57F25ABF2349F495A10DB2355C3F1D1FBDAC0DFBCB7762BF7C988C57CA84ABCF652EC38F1A0DFAF5FE58FE14302EBA8B3AF7C7201F53D56AF03A17CC8C3E4DF1B826F810623446BDB7A74FB76C5724642B3E707DDDFBD484831F53ABFD399E59DD52ECCCB1BFB114EC7B67DE37A262474D8668ABFDE025EBF0D76823CCEDA5D85E7C45C3C5E15F911351C70EDB03F4151F350894DCB6742F3AE01EB24F79ECC82D907C0524C900FF3C8137B4A1C31F491654E7DDBECEB6CBFDE04AE5BFD57C3C8B6CF66E3A727C9AC68D1EE16495D867085B6A98B1D4CBBAA1E524BFA3549C3EBDCB68C6D2E17A33D3AB53AF60D374D2D56633B4D6104D9AA23B079D95F50E67BB49E0FF4084180C80DCFE60D2A084B3BCD2D5F67A21F303225A16FB28A237395CB42B64EB2B612EF47E6B5693139708736B5E5929CA13C9D6ABCF6F5185D68FCD3521D539116446A007AB5F21D6A5F43D4C9997553CC904C20A55FA3BE59ADF6C8BBEBC80B3BFF2783F5199643FA5D95ED7D204DEC3F11FCDF002B7E5ADC22376435B496F0688997FBC7D75A080B21A6C4C14047EDA8DBE73590FC1A2F73F8A5F2EF76231F49F80FCD0C1C2A08045BF2035403A9D408AAA1E6E525A24C59AB839E1AEC8253C582D66117D4C7 +ss = 54DF5956155EB8EC96F4BF24A1E85984B2376FB0CADC4A51DC5B15B78B91C7B9 + +count = 62 +seed = F7AE036A0176A9DE9A036A542DD2840033277C44AE936D10B768566216DE9D4395CD42B116873B69D9804BA6CCBC05D5 +pk = F482771DC2C9858AC8530CD028189A440EC72DDBA264D77E4E5E91D6B1324547BE51D8BDE2EA4FD968B01733BFD16F3150048D9E8B069B501AEAF267D0526F2060F02E9BD861A193D8E97DB3B3004B777C4250CFB47D4E028CF6A12CCC39DF207A7910D32E30B06AD15B4538632D25E18608250C3040BDC77C5F388C86C6E8616A15812A7BA3EC3D4BB72F2EF5448B410834837327D7699664893B633F0FE44329C99DE8E37CBF3B5150450093804F6BE1A234B34ED85E3BC1B906076FD9A2769A268D2A4537A9EB4DAAEC8CC92E9B2D9F100D440E6025C8CFDECD3C308B4047F942F64CE026E84AF864780F4977C01D9FA27B8D95B552F68335638CA3FA2701CF08D42E7DA7C36337CCEA9822834FCA2BE1D01D5111E7D20D0E6584102DCABB5C7D27ACDDEC151673C20EE1B0E7D610352C72CDF9591F0D224FCBDCA4E8DBE7FFEB7E7FCFBA3EFE706BB57E6750CD3F4A2C5373375153070F2DE972E2A83D9452FEFD23FD96F69C9C2F03E14DA3B7B7703FE97641440736D53895CC7B296082595CA7B7F2A4E2274C3C12ACEA860482D556AFD29509E6FC0326CB1A065F0BE1E64B3FBEAAFE63EF9CC159C29BEA02381729CE65FB16FFE5D666FC615BE67FB4661AB963F916763F9E543C6D488E964195AB0213701F3C78988D047EC444AA6859C22D24076C3964A5C4170F5AD3CC78881A1C6C31B39D3957BAD2ACE33D750546BBE6A498596DA101E09BAE00638421CAACF6D91303E5F87F2FE4EC049C2A481DF57BE64B74C72C286ADE8B9217BE19E5B00300 +sk = 6500F32C93415CFDBC0BD31D78D5BE95CB9060C8CFA2013955B56F8B6868B322393308641A9A4647F230201E1389624A296B55192A9819FCB19AB77C25F954454E963EB0D01B937D6DB5EFC6661AF403F482771DC2C9858AC8530CD028189A440EC72DDBA264D77E4E5E91D6B1324547BE51D8BDE2EA4FD968B01733BFD16F3150048D9E8B069B501AEAF267D0526F2060F02E9BD861A193D8E97DB3B3004B777C4250CFB47D4E028CF6A12CCC39DF207A7910D32E30B06AD15B4538632D25E18608250C3040BDC77C5F388C86C6E8616A15812A7BA3EC3D4BB72F2EF5448B410834837327D7699664893B633F0FE44329C99DE8E37CBF3B5150450093804F6BE1A234B34ED85E3BC1B906076FD9A2769A268D2A4537A9EB4DAAEC8CC92E9B2D9F100D440E6025C8CFDECD3C308B4047F942F64CE026E84AF864780F4977C01D9FA27B8D95B552F68335638CA3FA2701CF08D42E7DA7C36337CCEA9822834FCA2BE1D01D5111E7D20D0E6584102DCABB5C7D27ACDDEC151673C20EE1B0E7D610352C72CDF9591F0D224FCBDCA4E8DBE7FFEB7E7FCFBA3EFE706BB57E6750CD3F4A2C5373375153070F2DE972E2A83D9452FEFD23FD96F69C9C2F03E14DA3B7B7703FE97641440736D53895CC7B296082595CA7B7F2A4E2274C3C12ACEA860482D556AFD29509E6FC0326CB1A065F0BE1E64B3FBEAAFE63EF9CC159C29BEA02381729CE65FB16FFE5D666FC615BE67FB4661AB963F916763F9E543C6D488E964195AB0213701F3C78988D047EC444AA6859C22D24076C3964A5C4170F5AD3CC78881A1C6C31B39D3957BAD2ACE33D750546BBE6A498596DA101E09BAE00638421CAACF6D91303E5F87F2FE4EC049C2A481DF57BE64B74C72C286ADE8B9217BE19E5B00300 +ct = 7AA5A74E78FA4BD7A78D173282516D2FEF51DE000FE2E00147686B5DE310F5F7B39A88EF3D6201D510599EDE5AF0BE942B4327BF8F4E30C6D50F0DD4980C3DAD982992930282B7F0D9113E5A861E395C09097CC813151D17439AEAEA5F1604949368BDBF0BD40D360596B32AE7037E95BFEB05B00AFCE979F7C308473ED924888E61F92310D28C6C8647BB38CAF77EE5D0D3D61A737BBE6B37636FEEE3617A95D58EE9570745B4E97F76BB3A47BC0F2C0A722207B51D5E035083A061D871B5E3EBE5F35BA96A0A50189792DC199DDBDFA93D9D4414B2FF696E1D61F492EFDF88C851BAADEE7CEE6D283FE9DAF1A599F41DF9CCDE71C6409EFA49367D998C8EF0FAC44B4A4BCC643256A3D2B5C5C9C1CDF41B30C0C38D32837F05D6AD3207E912313FE3E0ABBC803C73EAE9A04E89D29600CDC391F73A49896F36AF95BE5A7C272312943A80AABFA0A6DD8DE77E5FC37A1DB18262D52AB1DA2EA9FB26501915C4D2AB8C54773A5B40F08A3C8394116B7724B1286398A79D282BBC4141B3C16378B89CBC22C61243011B05D097B7801C6FE3C814297558CF3F23CB02A07CE1AB3A8D060B7562C31453216231D3F9FC99DCC0EC31EDCA9E86C0067AEEE995A5241ECEC880A827A7FB80DB90346A2C1CB965947D91016A6541EC1978F31E58F936D92DE2A46EAE0178D58DBB69717EEBF575689A21C837537B978EB51112D82B3F34FF156EF8F36A7643E2C612DC5B958849B388C06CB9404800EDC06155ADB4B5D73848DD88D640FB65BA00DAC7AEAA9279A5EA2B1A31E80D7044EFBBC1B509E9FFCAD74480C71DC22DE821168CB22A4F400E6D3348 +ss = 1BEA35EECCA0EB3A88C2E9366E1AFE6E263921F4973F8A69E37E2ED15621FA92 + +count = 63 +seed = D995D38F934B6E1A7CA77C9522E3D037676CC939B0C8BD4B84394B3DC91A791F09D2D97199258C9943DA955E7F7B26FC +pk = 106DCA703C5EED03312712347F2B74EC3AA978045200AC5D569D5335DD8AB19A77D469EEEC95DB59DBF748C5EBC592A9A1975F4A2160369B48589A6A7FED06AAF12A3E7D51BC07281F99F05A4B2E76CDD81FA339B3CEB9253051425B9F4796CC9C4D4DE3B5502939323A199888D3307544907941186C994CB55197CABA62CE95CFED06F5399A06279AE1CC2652789F287268B6B72DFC7E112005FE943850A43A64BD8758DFBDE892C09058D90D36E799450CD067D53EB30310A02C269B0DEC00A6D96E9D85D4628C538BA89E164C7ECC09B7959ABE550F3ADA0C05F7666076D7A1BFE924CF64830E4F16E39E00FE2465A2D9B3BB82D369AD4D5C45C089A28351A28079344210CBD6FCC2B90865253B1282319A7A950920CCFB15F105AB559EE4C312D005B1DE64A932FE524376A5D163F442F2F4D5A6E73C8515E23601EF4F9631CF25F1F7B211CB2D60208EE1F762EA39AC8F71141A36BB66007D9E066C76DEB9DD870D7ED9E55DA515A75093B044E3B7B642B50743E510CFFD343913B86F54809658E8098BCCA42BDAD4F386D3E532DCFD29664B2F486A62181CFEFF0A68E756D2D348DE56EE251FA1634D285E49130582001D7A5B8E8AB5760AC6249961501FA2A0452E49798FE005721A5F24DE1311EC59F6A1594D36439EDB21EBA0BBAAE9ED5F6746D695ED0DF54891E9CF1D1795DE86FFDAE8ECCA8AB91E4D89512F7E9B3BB3432544219AA57D66486AA21DC9F2886BBD7B618AC61674B908A356E7DE5C2048E26BAF6AF82D231DADD61B5EA6C9310D4F +sk = 7643CEF2D62CC5AAEECF754653EA62294CD2208E5BF3DDEEA209E3DC45373D49EAC9D531A532770837A854B4F5531F6E0C8D6C10183B30D3435498C2DD142951EBACBC33859B828F9FA95F5C4C114702106DCA703C5EED03312712347F2B74EC3AA978045200AC5D569D5335DD8AB19A77D469EEEC95DB59DBF748C5EBC592A9A1975F4A2160369B48589A6A7FED06AAF12A3E7D51BC07281F99F05A4B2E76CDD81FA339B3CEB9253051425B9F4796CC9C4D4DE3B5502939323A199888D3307544907941186C994CB55197CABA62CE95CFED06F5399A06279AE1CC2652789F287268B6B72DFC7E112005FE943850A43A64BD8758DFBDE892C09058D90D36E799450CD067D53EB30310A02C269B0DEC00A6D96E9D85D4628C538BA89E164C7ECC09B7959ABE550F3ADA0C05F7666076D7A1BFE924CF64830E4F16E39E00FE2465A2D9B3BB82D369AD4D5C45C089A28351A28079344210CBD6FCC2B90865253B1282319A7A950920CCFB15F105AB559EE4C312D005B1DE64A932FE524376A5D163F442F2F4D5A6E73C8515E23601EF4F9631CF25F1F7B211CB2D60208EE1F762EA39AC8F71141A36BB66007D9E066C76DEB9DD870D7ED9E55DA515A75093B044E3B7B642B50743E510CFFD343913B86F54809658E8098BCCA42BDAD4F386D3E532DCFD29664B2F486A62181CFEFF0A68E756D2D348DE56EE251FA1634D285E49130582001D7A5B8E8AB5760AC6249961501FA2A0452E49798FE005721A5F24DE1311EC59F6A1594D36439EDB21EBA0BBAAE9ED5F6746D695ED0DF54891E9CF1D1795DE86FFDAE8ECCA8AB91E4D89512F7E9B3BB3432544219AA57D66486AA21DC9F2886BBD7B618AC61674B908A356E7DE5C2048E26BAF6AF82D231DADD61B5EA6C9310D4F +ct = F598DEC8DFDF9210149B10610007EB99FF08FA7F063F9CCA8C05F5FEE57F729B1A7B127BA01061B785D05A0A7016B8C04C61DB7251046B1FDBECB45A2FD610FB3E6F6A3E2FE1D9F403A7ECC21F6C1E5586C17076DF0B64F4373DDB91326067A832A5BC7B93ADC1BBD9A89600F4BE549A525D9922B426032EC664D7325970E99053D140CCDD5AC6E34F6E5FD383C875F0ADB12A5682423E56B44656FFCBDC63F47188B279F173572A2D2E807B1AB020D600ABBE6DADEFB6CDE4B8EE40D6D09746609BA09F85C80FAF3EFE78FCAF871DE5F1DCF00986D1BAA1323C3EAF5BDA3D307381BE5F5DBE18CC7867E4435083CDBDE90431E3E312B486E8E5091502826000C9B68E8D6FCDF3D087EB0DF9D628ABD261C9DBD9805A0DB00F68ACD59D666104A6B07462875EE1417C3673C64C47AF10E6D5A97E3FF72E3CCFC3B223F12C4A8F2601FDCF59E4A81B8B9DE0B2E12904B0817F2BADEA9CDA26F9E72EE5D4CBE475486439D0EA63A863C254774561D3E9C8783B819DC5949D61D4B2E311983B1B342D77D1F31A73D8CA9F617319F4E2B1CD1930BFC2B972B00EBFF54176D0A949C374242AD39F4007B52958D26BDB636E46522AADCF70FB51F1E6213EC58F716AF47EBD2DCC3A5E33123DF19F53977A472D32DCFC4264064E381A4A7C2468BCA7F406C0FF2704FFC450BE635C098A55185653539B0F8EAE6C1E5770423CDDE85CE815F52276BF9AD0215BCD256578A346C746EC8BFF48B3E78FACCD88C62151CC8F60595ED055A002FB2A6C5AA7BA2B1CC05F5B2765531C107AF151950C50CBA52CED2CF6EB5D972A3950E0FC3830B729A71C5A7066 +ss = 0C77A265D4D025CF8A1234D18336AA4E635A7D5F52C058AEED0A100656D701B3 + +count = 64 +seed = 5929F02A271725CB40200DE32D9D03D8BEA53B53AC83186C42C7F565CCB1CA508305D470850CF86E9B2C61A5B8CA1C93 +pk = C248D6FD6975EB9792FB099604045EEE4CBBAA4C9F18F316F40C23F289221FC194019C8675C2E938E6883F801E35CABA31EE6F8821B24157F042654C927C709D080ADD2FFC5D8D858C653BC22072001FB6AB120BFBBC048771B13A08AD6877714A20648E8D80387192C2ECE2608E7BDB0209FF563741664210047DE903F77E64967F0ACC45CF44AC4C086B35BF76ED2B0E678EEA6D455FE5EA22F21E62B58FB121E85E1B56C9591686274F21B12454EA42C65FA45E653F088081E9205BBAA9F3201B494D96FF74243E8A379051D1F832C0231D5CF79C01DECDE269EFE2DD30E6FE2A5FE39D80E232B14519BC94DE0373DC3ACE4F41C1D2167468D3DFD307D6D96AF10A3D02335238361D28175D45A1D5530CC940277FA678A74E0AEAB71918A92D96A27F6528F51DA77ADB6FF07C91180FB7CA485BD09943E42227226B7B313E1379DB76F7689CF2C9B4A982682FF1F7653FE437199A0A2A1679291113EF48A71B8D5422D94BD92C45853484BE305F4D3E908FE6B0E9120950DE00966864012B2B2C530FDB0512DD4ADBFE9FB41336707A77478837CE8C0FA8A285E1A6ACE96ECDD508D55887DAB2FC656B2AF1C129969E0EEB7FEC451C858BCDA570F534C80093E034B26EA26AFB8E7728C3AF44A690CF2587CDE042662FCB4FD5496C9C853EA551B77036F905B156A210FAECA83E6C85F32C8E293FAA98B9B235AFB9B6AD2EB79E3B1ED9F64405A56885CDC0999083D8D30ADF1C729436329C204EB4126DDC017261A9AEEDA1F42B305F8012C92E0702284C44 +sk = F8EE95521060C03BB8DACC79F7EB7DB640F545F315613A35D447A09E504CB4E13FC3D8392CB53F36ED647364A04E37278A0E0A45B720F4A75C580C9920EBA98D497462F26B431E889F56A33FC9499002C248D6FD6975EB9792FB099604045EEE4CBBAA4C9F18F316F40C23F289221FC194019C8675C2E938E6883F801E35CABA31EE6F8821B24157F042654C927C709D080ADD2FFC5D8D858C653BC22072001FB6AB120BFBBC048771B13A08AD6877714A20648E8D80387192C2ECE2608E7BDB0209FF563741664210047DE903F77E64967F0ACC45CF44AC4C086B35BF76ED2B0E678EEA6D455FE5EA22F21E62B58FB121E85E1B56C9591686274F21B12454EA42C65FA45E653F088081E9205BBAA9F3201B494D96FF74243E8A379051D1F832C0231D5CF79C01DECDE269EFE2DD30E6FE2A5FE39D80E232B14519BC94DE0373DC3ACE4F41C1D2167468D3DFD307D6D96AF10A3D02335238361D28175D45A1D5530CC940277FA678A74E0AEAB71918A92D96A27F6528F51DA77ADB6FF07C91180FB7CA485BD09943E42227226B7B313E1379DB76F7689CF2C9B4A982682FF1F7653FE437199A0A2A1679291113EF48A71B8D5422D94BD92C45853484BE305F4D3E908FE6B0E9120950DE00966864012B2B2C530FDB0512DD4ADBFE9FB41336707A77478837CE8C0FA8A285E1A6ACE96ECDD508D55887DAB2FC656B2AF1C129969E0EEB7FEC451C858BCDA570F534C80093E034B26EA26AFB8E7728C3AF44A690CF2587CDE042662FCB4FD5496C9C853EA551B77036F905B156A210FAECA83E6C85F32C8E293FAA98B9B235AFB9B6AD2EB79E3B1ED9F64405A56885CDC0999083D8D30ADF1C729436329C204EB4126DDC017261A9AEEDA1F42B305F8012C92E0702284C44 +ct = 43D6230FC58B366914820994BFDBEC7BB7CCFE53D38CE8ECC8D0D53B123B2A087867DAF9B77E219653A21CB9C46FBFD6359A29BAB7BFFA9E72CE7E5C793D96F98E34871FF95D5FB68678AA81B31DA196A04763AB4DAEB489A4F3BD6FCC64F357E56BECF3AAFBA8C461E27C59274829DD6769E4DAB4E05CE7683602FA7C252FC22C68834E7CFFD6D13E2A2C80F8A74F8B71C8325881635EA52591024DDDC1ECF61773AB04DE22D2F6160670C57AC29D8813BE1ACDF549557AB18ED455BD9C771B0EBDAA653DE8DA1B44CE2A5271FC110926FA87B67D65F68348994E2FF0EC0577ADADF38460FC3229F66FD4D58E0F1258D195A3A678C2F608D6DEF8BA8628ABBD766BFFD1B90EFDA25605706750FE4062763F0D3FC25AEEB557169BB895E2DDFA650D7F3E4D8429EF3E9EB360D9E4C89B890605925CFE0CA5E489D46F07AA7BEC731C75652577B1E4FA189A322C5124495BDF2176EFC11FCE592919B744130C8AB2F935CF4966BF6E550DCF8F88C9ED06A168A7EA3F0D5736282893E9E465FDA9AE9041C73ADD50CA16D10992C989C5FAF10BC3877DF6AA11EEC8CC672953FFDB1A0B9FC29F84A6C082D4D97DC76963FB46FFDC443E5B1A1C08BB122B0F387F7E170F8626F13C2735217F8D9906B16E5EBE438D24BA340A07951C85A5B4265918022AEAC76C9D1E01A988F145B57EABA6C125B40EC58FD7A22726C142232D2AFF76C44FE6B35A6A746546C8F00E6E9E323656D584AAC9147D547A282D5508792501734CCD5B6B16694243BFC3CE18BB66A31EFC46B620C91F421F36D1F65D83F2D363BE17D0D2B2DA3EC848834D29644C78CD94AF +ss = 643DF928F7681C94AFC18C6CC19F2FA446FAF7D7F38111D42C4BB3EB3F09292E + +count = 65 +seed = 905074033D7B75DEB2D06A2F29144EB377B452534C5710632989F02D45312D156557E96D4486020826DB200153BC4A8B +pk = 60BE950C205ADD610A28C56D5DDB12EB94624B3E0648144C58622CF1A66B93FD7FAA4BEA9AD2C86E59AEE6C729F915C41E6A4F4F54364F5E3372435091DBAC3066CB6BCD7BBA7054D20F9265E62A31A3AF46A9BD6497A0551C6A46E6711B16791B441D1C29A62479F18EA4864658B5E13D8F40E0BE6526AA0E46BC96471E836175B4426A30A76E9357064F9F0392BBD2F941290B0C85DF85ACE5F7CD08A4939D1C01013C528E8343021AB4649998376F1C5AC0A99D4510FBCE1C74423C2F8EF266303C46BC738C367D703BA280CCC15ABCC83C5F1B1D6F7315FA5151FD01649E235C2A3B2303E2B5751C92C6C5DBC1FFFE59CC94F68A0D7616C933AC6F15BB72EE513409FD0EBE24E42286F5CC7D8C0E94494B2490CD3941035C8504D32CF946A418CEF3C34761F7BC3A42B90FA38DE8CAA6AF383ACF4A27E7F039162B28A44226771A74166885E010BE3F8BEB178EEE323184DEBDCF777FE44485C4F52572B86804DF1B4D7B89BE5E2F7573CF6E7DA19FAC483AB7E4602FB6FA7919FB098DA69452105B30861C06CF31DC9A3CF4BA0A7E3D3EFC5F75F4A35996E38673D5ABA8BEB8306C936430733162678A9EAFCEE6B1E25BAC7DE7DCA4D42731DBE59838F93B50B317F77AD03FE8FCEF9043D2F22D164FD3194139A734DDEFE42880833D661EAF062A7E769ED7C5E11B1867523649DE2A5FB3EE781C4F5CA369E91F5509CD9E4FCFA34A39019B35FD9B1853085EA877B9FE49D58C4E3EFB26F15291C49C1772F1D14E5BB721577F3C3B4319EEAB439D7C7401 +sk = B8BD0493A882E3A49B4E0F6256FB1FEA0912562FD9BA26EC3D6C9CC12C8973ABD7E4B5D8021C486B9C3114D7CBBEB7CD49EBA8A61BC2BCAE1F1BEF30A1DAF76DA93BC0A2D45E032A1546012E75DC8D0360BE950C205ADD610A28C56D5DDB12EB94624B3E0648144C58622CF1A66B93FD7FAA4BEA9AD2C86E59AEE6C729F915C41E6A4F4F54364F5E3372435091DBAC3066CB6BCD7BBA7054D20F9265E62A31A3AF46A9BD6497A0551C6A46E6711B16791B441D1C29A62479F18EA4864658B5E13D8F40E0BE6526AA0E46BC96471E836175B4426A30A76E9357064F9F0392BBD2F941290B0C85DF85ACE5F7CD08A4939D1C01013C528E8343021AB4649998376F1C5AC0A99D4510FBCE1C74423C2F8EF266303C46BC738C367D703BA280CCC15ABCC83C5F1B1D6F7315FA5151FD01649E235C2A3B2303E2B5751C92C6C5DBC1FFFE59CC94F68A0D7616C933AC6F15BB72EE513409FD0EBE24E42286F5CC7D8C0E94494B2490CD3941035C8504D32CF946A418CEF3C34761F7BC3A42B90FA38DE8CAA6AF383ACF4A27E7F039162B28A44226771A74166885E010BE3F8BEB178EEE323184DEBDCF777FE44485C4F52572B86804DF1B4D7B89BE5E2F7573CF6E7DA19FAC483AB7E4602FB6FA7919FB098DA69452105B30861C06CF31DC9A3CF4BA0A7E3D3EFC5F75F4A35996E38673D5ABA8BEB8306C936430733162678A9EAFCEE6B1E25BAC7DE7DCA4D42731DBE59838F93B50B317F77AD03FE8FCEF9043D2F22D164FD3194139A734DDEFE42880833D661EAF062A7E769ED7C5E11B1867523649DE2A5FB3EE781C4F5CA369E91F5509CD9E4FCFA34A39019B35FD9B1853085EA877B9FE49D58C4E3EFB26F15291C49C1772F1D14E5BB721577F3C3B4319EEAB439D7C7401 +ct = BFB678D1D383D88AC00D3D9F0820819A775D0403AC86C4EE15C745F1FD0C0C92768130B2A7524E0591343AA0E22B8FEE7380484186A2CCED06FC02E06CF952F907201ED02B08AF4AF293E33C06942BBF1F86E6607BF00734341F63F1AA33E9756812005A6CCE3A79EFEA110565C6A63C71EC96572241F2756023EE5D5C26A5AAD1AAD61951BDE38D1E53ADC7F6CF6C9088DDA9F02152371324C6DEA42154456837B0B7364D5A824F37279FE0789056CA2E62A41BA5E5B0A48D81B65651CB9D846CF816A478A82428605FCE85F6DA6EE450D36BE04D6982B1191DEB8671CE598604FBD96B7F4652F1DACEC0164570ADA4C933212F46105D09F0EB9CD01847162AA2A31F6A0765E51F05F0AEABBF1D644A0C971D6E64774B170F175171F415B14590492A71D65E97212AE62BF1A2B61C258A5A5E1158ECEDCA37AF7346D88DA218D9EFDA1CC850C842D308F4D0117ABD524CF57DA0BE6A221EF4AB1D022BC36AEAA85542BC3E4A9866864736121573C14CEEF7D800A8C3993D1F195345D265E8D1B5E2BE2ADBB82E4BBAA8A86A02D310741842D269EF390B800462B1AD4FCCF35E00A89A1FAFB10FE2E4EA74BBD03A37034D23835276FB4B338323450A6AF4D5E2EDB53E2FBC93970781F44DFF028B84C0CF4AC70FBE3A4E140183CBE65AF8EAE11E5D11CEF3A2D1B967A63FFBD3FB65F4C187566EC72A36000A773F29851844FA26E113FBECB06FB7FFB696FC38248F23F8E5ECA707843149B7AB40525BF6D4D8639FBA76AA265F66FBAE5F287DB72ACA63988E33B8BDDD89E0D71CFDA88E2660EF84019CA5F9254E469FE65428F64EF32CCFF7DE +ss = E39C1892E0D8EBCA1E85DB794E65C5F5954FD6929E64FDCAE0E5B47EF2B46A5B + +count = 66 +seed = A3E2E511AFA7BB560446BDADF67D2EE2E16FFC7BAEAE7EFB8C5455068BBD4E91BF9BE9D98B280072FABA7712C75B26D4 +pk = 4DC123456FF5AE84F07B2C68C9AE20CA77935E79923667505B3A1BFD6C8E01F161183F45EA8A1E7453AA062B1519C93D27778BF8DC3131028AF734FB9391AD66C3B4AABD3B1B6703D29CFB49B32A340B5C076479728101548448A8D7130FC5FC7D16E3A87BDF9F3045A2831400A20730754B9FD5E96617A04B88F052D67F12775A73AA4938BFF263270C737DE1DB372D3A92A7B4B8CB59ACD9F477B0D017C312981FCBB3DD4C2B2C1E6CF361A20F9424485BA0020C6928EA3293274B90085293DB9ADB48D62C8518FECDFBD9EBD3C8B476239D0AD8F903A2A5E96718B31774182C7BEFFC769B89425F96AFCF2BFCB4059116375882FDAC619EBDF7461B76213A5BF15DEAED595347FF00D186307B7B0D57C0EC9BCEB6A3FE5B3B38F5DEA98D7A00B10C7D3E1AFD6F5E8EFBF5124572A9ABEA6D01C58AA4DE6BD960B49CB99C6B2FEB47ECDF100E35071EA61963FE388E225B52C9758569E4A4B4D1D1DDEDEC166FE140C0008CD26EE3AB6AA8B7F430642C8986E439F4155838B418D94DD7CD9135DAFA61098B5B002A74B713D8E38EB6FA0280449DC6887B539C7F7ABB0D837E458D96BFD287DED61F7F0760362535327A4FBB83795F92448755170BF11122D57787F759E3DEBBE2F4E69152F1AF63286BEBA3C1A35D044AB5F8C238E21E250CFD4AC23891711FA8CD034884BFF7514008FD6AD72F4FE4F7E85FBB3072E32664BBD2D12B38F6F85338E5B46869D164F351676D49D2CBA44605A1226FB0A30F4E9B955F5BA5D48E44EA65E5901520D29054A19035 +sk = C0407E41DDF48D333978B89BCF2DB01E4613425B456249E76A6F25B8A2827BF5B2DCA81E3F5F748D23C9D356A2209F6B2D60247B2E45C9808DE497F64F1246436D0AE40E7A499B148DF04878ED8982014DC123456FF5AE84F07B2C68C9AE20CA77935E79923667505B3A1BFD6C8E01F161183F45EA8A1E7453AA062B1519C93D27778BF8DC3131028AF734FB9391AD66C3B4AABD3B1B6703D29CFB49B32A340B5C076479728101548448A8D7130FC5FC7D16E3A87BDF9F3045A2831400A20730754B9FD5E96617A04B88F052D67F12775A73AA4938BFF263270C737DE1DB372D3A92A7B4B8CB59ACD9F477B0D017C312981FCBB3DD4C2B2C1E6CF361A20F9424485BA0020C6928EA3293274B90085293DB9ADB48D62C8518FECDFBD9EBD3C8B476239D0AD8F903A2A5E96718B31774182C7BEFFC769B89425F96AFCF2BFCB4059116375882FDAC619EBDF7461B76213A5BF15DEAED595347FF00D186307B7B0D57C0EC9BCEB6A3FE5B3B38F5DEA98D7A00B10C7D3E1AFD6F5E8EFBF5124572A9ABEA6D01C58AA4DE6BD960B49CB99C6B2FEB47ECDF100E35071EA61963FE388E225B52C9758569E4A4B4D1D1DDEDEC166FE140C0008CD26EE3AB6AA8B7F430642C8986E439F4155838B418D94DD7CD9135DAFA61098B5B002A74B713D8E38EB6FA0280449DC6887B539C7F7ABB0D837E458D96BFD287DED61F7F0760362535327A4FBB83795F92448755170BF11122D57787F759E3DEBBE2F4E69152F1AF63286BEBA3C1A35D044AB5F8C238E21E250CFD4AC23891711FA8CD034884BFF7514008FD6AD72F4FE4F7E85FBB3072E32664BBD2D12B38F6F85338E5B46869D164F351676D49D2CBA44605A1226FB0A30F4E9B955F5BA5D48E44EA65E5901520D29054A19035 +ct = EE8DD7AD12C06F3791A8E4283721BA9EA832D3A8FAAB16992DB5D6BED2A628B9C0E59D80B5E854529FE4714F11FF4C7B79C293A9703177A883802E88A772E12D535AF1568C608D53F132FC61A705681E1E6D16EB8BECC8A7592F8B04DA28C3C19FD760768394C3AE0DAD21A8256BDB1572DBDD8CAFC7B5A4C60F8DCD7841CA146B89543FAAE8447C6FFB6F57D10BE110DBADD5AF6CD13E83D27193787E7D431B0DFE03148601859C75F02782CDD8F28A01178EB19B3B55816C5E01140DDCB74A9C77DC1BAECD7F00F256DD6F81120595B6C3F86C64B2318DAB1DA67FAB1D821548863B441924539F16A832D734963B344B610C336CBF3494AF8A32B9920294598BCEDBE354D3172B2D53B4C18F4E95DEE8787D9AC6083B77970D99E12AAA4C922DD38F2C9732ECDBF4CB92ABCAF61544FC2998CF5008C7B512FA8952D91A24FB57D90E76EFA99DAFA191A530846214F81CABD8884B56C4774592E29737008FF1D808EEDA323988494884E67E44F5D16C9D09DCEF91BDCA305189F73D1D8C702FA07697FCB09EDDB8EC7618AF6350E21BD952B4492423787597AD94BF1F6FCA465FA2770BB300E56573BDD8DF8100352ACC0BA9F1AE227644F0D4038CD31D97BAB544583E986E01C646EF95A31455E4741DB7E48DD1639BF7C16376777273F3F9B370790CDF16B15B52082FE1E6345E076BFA068050AA0BEEFBB157ACFE8D71D213CF69604047BFAC9B23BF18FE36CBC8F8C899329A548FB1E9C815DC440431F6916D300504489EF3F1812C872C65A778A201F90762DA8C2EFDE53B04B0EED1B5173A9DD2E03C8F85CC7E0B70EAACAED18B0E7EEB +ss = D4835589F1FBD94049273F28D19D358ED11331E6F1167B42F48ED20633705506 + +count = 67 +seed = 074AB1A37BA5A0403D8F68D26FB787BC2C90F5EF88F2A6D286C3E6B168ABD85D393D8225618608B8EEB301D26AF53BC0 +pk = BC147B3779F6624049B7DD2BA7E78A329033BA5665AAF1279F96695D7DB1991EF639CC3B045757AF4659F6003710EA441F33297863C97DDA7630F678C398F7A01A36BB62A05439C3BBEF0BBABDA9767C55D8D9A0C79C199D660903015D0E61FFB87094DA18EE616E261AE3E0828C033787880F429D1149FA263F62DA619F6AF7FF6087DE2D0207F363F333785775079CB6F1F9CDEB98A16DE28B633026C263B4DB845DC979EFF1C1326C1C80B7843C4F904DC0832E3EBB4EFF38A84E38CE267DB870EFF1430073A01212CA694A79662C8E5D00B0C28E067DFB3D3CC4CBBF7B0C17975DF306175110F383C431F09A9218F529F07A283DD70925B3AF21E13AEB5A622BEBD3C5CBF2E1D399089DFBA9371B0D9885B76DE8D88F73542F85DB7508122578E7D4B960C772842C452BC44104300F2B6C8902479D03B71B703DFAB5198AECE4DE304546B520BD68603AECB25BF473F7B81DA29E7624E610236C0DF25F202A32F172E6C55482C9A02399BBC4DDBA41D3544C7D5F5960FE519E08CFA56A853EF6D0086EF5D905C2DEBDBCBCCBB55C65BA89659F4A0B9CF5E5AB7B836BE2744D74BB3AC8E53F30C1481D1D1C8520D658A7016BE5A091B279FA4F28536656A3D4814096D87CDAF8314C52F71637202E7F15F8829921EA57CF070277704C18B0BF12A8F7362EA0C070C650A4D1AF4998859C4A641FE7D2072C41C33F1C6478AB9568D49DE213B5F0A43AE8D4E1527F051145227B44E109665802CCFD55378A051154130B0BD4CDB97E86A524C702114B224A5310 +sk = 334382D39164D1989696A2FF77B25A28AF8BEAD9883B5365EB6FCCA7C1781CC9ABA5068AF837BE962F439F233593D193CE5E08F7D66EFB3389885927B89D252397F0169ADCCE240CCE953AC7B438B901BC147B3779F6624049B7DD2BA7E78A329033BA5665AAF1279F96695D7DB1991EF639CC3B045757AF4659F6003710EA441F33297863C97DDA7630F678C398F7A01A36BB62A05439C3BBEF0BBABDA9767C55D8D9A0C79C199D660903015D0E61FFB87094DA18EE616E261AE3E0828C033787880F429D1149FA263F62DA619F6AF7FF6087DE2D0207F363F333785775079CB6F1F9CDEB98A16DE28B633026C263B4DB845DC979EFF1C1326C1C80B7843C4F904DC0832E3EBB4EFF38A84E38CE267DB870EFF1430073A01212CA694A79662C8E5D00B0C28E067DFB3D3CC4CBBF7B0C17975DF306175110F383C431F09A9218F529F07A283DD70925B3AF21E13AEB5A622BEBD3C5CBF2E1D399089DFBA9371B0D9885B76DE8D88F73542F85DB7508122578E7D4B960C772842C452BC44104300F2B6C8902479D03B71B703DFAB5198AECE4DE304546B520BD68603AECB25BF473F7B81DA29E7624E610236C0DF25F202A32F172E6C55482C9A02399BBC4DDBA41D3544C7D5F5960FE519E08CFA56A853EF6D0086EF5D905C2DEBDBCBCCBB55C65BA89659F4A0B9CF5E5AB7B836BE2744D74BB3AC8E53F30C1481D1D1C8520D658A7016BE5A091B279FA4F28536656A3D4814096D87CDAF8314C52F71637202E7F15F8829921EA57CF070277704C18B0BF12A8F7362EA0C070C650A4D1AF4998859C4A641FE7D2072C41C33F1C6478AB9568D49DE213B5F0A43AE8D4E1527F051145227B44E109665802CCFD55378A051154130B0BD4CDB97E86A524C702114B224A5310 +ct = 4F89887713C19F0BEC9410C5A870C9FF924EA5CA038021A4357D6A683160D0E6C39C27FD802DD5C85F82A9D8B2AD258053A86E805E8AC1379977E6B0B92C42E115BD9CBA8D9F39DFF56BE767A8EA9D9568A3E127559A5719586E7A5DB419A050546FEF4D53DB0B40299B9F55EF419312947F8F24CB76F5EF3DF992467D1751FE50524B784C4AD786EDA947E76090B2A6309957BE96B3F177FA48197C96ADEE3C8E6E2D784ACD19AEA86CC9976AAEA1D40B5CF98C4DD893E003E21A622134C8D2D765AE3B4E730245545E27F0F018B99D1BE6F82017B088C81623F28F0B699B04D1D1B0810018793480726E0F58D5E5FE03B772902EBAF52CD9E0844EF3959A8704D17B130F7B4899AC9C42D46039541753E66948CC9872059D40F48A5F506E90715C37B1C0976CAA11D327642DF6185ACA3941F18A8765FC308E1870CE98760D697DBD325CD8D5AEEE8DAC38BE528AB6C9C9AA90965538568CAD943E2FF09B00A6FAB7981982E13EB5141216A1731A21811FFDB57D6B5F3C4160976FBCE82B10F4965CF60037CCDB58BC1FE02418DBEB2B30C427DFD18E78D23D6AC11DC7D1F1336925281AE0ABE655BE7107255C7CE9478C262E77BCFCB8002F581BD8EB8F8507B8B209D239557F688982808B050F5952CD93201544830237C3FE3FA314EF3A622D3B16226302541520059E82C8F659AB25D63E3A3A51EE14BB770C9B98F6AD614B19291A170FFB62C37499B1B3794E10E2F6DA1E8AA6DF2521392E299190B47130C25B06C4C104EB3A715245AB5CA3514A71046ADF90E2EC47A0BFEF518ACDC86AB819DCDAD4AD6931BA2B2F4F598A584037FE +ss = 4ECDE05F4C24C19F931695A8F6DED0DB21469A35A232792A2055E0FA129BF6E6 + +count = 68 +seed = CC0C86CC0ABF86FA21899BE1953913C00E7C46E6B5F730C4E88B3C034012763981D7F14459D3081638080378348856EA +pk = F028C7EFEAC23F7A9B7EE50C73D3041011862083518CA731D6496AEC46BD8A938F5C9BEA5EF04573DD4806BBF1EF8025E74255AB8FEC9A705BC373438D1F43E79FEADAA60CF5E138A54B96862ABE4B21994A4921C53400E856BEA19E5C58DB0812DA8EF2FF7722667D49F0D8A03B462CE8F7E94A2CF99597A5866C82F0A4E50756238EF872741229B52975E5F2B7946502F6F7D39584FADA259533F148B2E2F1E89CF06CA0099B4D25853B9F4F9084CA57927274C095DAA5AE4527269FB200A42F26A6997FAE385FD7162A341B2C8D86796287ABCE75DC9D3B3BA775FBF818F0A08FE774E7D0387021C5CC83D99BCE441BE8345A3741AC15B68265E50A4C9EE9715FFE494A23ACF7A2744768E6E2543B9556D0A230CF6A50F86D6B722272CA5AB49BD0221F4BBA4F6B353317B2BF9640F6F36AA798BD2A61FE0A62BC12D5064F483A833FD203A00058F8A9273E2AE281FC2ACCB443CF5F0F6F9CA03AF90ACFC4045271BA0C79B672CF871F61E49388555E02F3B03865634423B623A61D73A7FB8821996139BC2079C1FBF6036A40EAD5C14A3E0DD35F97E7388380AECC41F3F16513071F10407805F9AC44BFF51B676A2503CA16FCC9ABD340EF3209D3AFB6A09E1098B2C0EEABF1F22F02C32A7363D8A76DB2381565D1B13CE39735129BADC8D97BD2AC18FD3EDE3DDEE362489079B78CE0E28EE620C9A38706A16D4BAC64A6B7141A87C31CC17EAE37DDF77997084431201E353C1A2A03BEF410C607DAD61590C9691143E2E9B5261A515C59771C67F244B60C +sk = 6995143E8EB8A6E93840F76EEC844F67D2B5F75B1839A5040337E61F9806764A0F4DFF8E56F68440836A072412A30D851ACE2C7C6F02D60E7A8420001A63E6C6289AD9FBE5D49083E7078F73238A2402F028C7EFEAC23F7A9B7EE50C73D3041011862083518CA731D6496AEC46BD8A938F5C9BEA5EF04573DD4806BBF1EF8025E74255AB8FEC9A705BC373438D1F43E79FEADAA60CF5E138A54B96862ABE4B21994A4921C53400E856BEA19E5C58DB0812DA8EF2FF7722667D49F0D8A03B462CE8F7E94A2CF99597A5866C82F0A4E50756238EF872741229B52975E5F2B7946502F6F7D39584FADA259533F148B2E2F1E89CF06CA0099B4D25853B9F4F9084CA57927274C095DAA5AE4527269FB200A42F26A6997FAE385FD7162A341B2C8D86796287ABCE75DC9D3B3BA775FBF818F0A08FE774E7D0387021C5CC83D99BCE441BE8345A3741AC15B68265E50A4C9EE9715FFE494A23ACF7A2744768E6E2543B9556D0A230CF6A50F86D6B722272CA5AB49BD0221F4BBA4F6B353317B2BF9640F6F36AA798BD2A61FE0A62BC12D5064F483A833FD203A00058F8A9273E2AE281FC2ACCB443CF5F0F6F9CA03AF90ACFC4045271BA0C79B672CF871F61E49388555E02F3B03865634423B623A61D73A7FB8821996139BC2079C1FBF6036A40EAD5C14A3E0DD35F97E7388380AECC41F3F16513071F10407805F9AC44BFF51B676A2503CA16FCC9ABD340EF3209D3AFB6A09E1098B2C0EEABF1F22F02C32A7363D8A76DB2381565D1B13CE39735129BADC8D97BD2AC18FD3EDE3DDEE362489079B78CE0E28EE620C9A38706A16D4BAC64A6B7141A87C31CC17EAE37DDF77997084431201E353C1A2A03BEF410C607DAD61590C9691143E2E9B5261A515C59771C67F244B60C +ct = DA833767C3C18F3F649C0D028D1BC674ACFD59913CD7F09E1C47689E7A80D1AAD467A4BAA61360C83755C0A528350356B13B739186281008D78C557698C827B2C079E7B68A1940E1AD60F0186F176259AA474D8CF464574A2C0ABE30D339D74896A0BD48830BF8F30FA33C36D776142D8EB786953D038377E54A9FD3230894156E254A1E1DAA26F7655014C3ACDE2DD4C1C7487D1FC8E0797F6CDCB42FFE7FD82D77B5FDFEDEA65CE76FA79ECE6C1F973BE239A573900FE2DA0D78464045BFDEFE0C3E870B7AA446D03D1C5B26F2BDC6C3CF6A94B0039F4A66F026F8847B9861C0C022BBAEAE255CD5407699326F4A653A777AC84EE17007C40E3BD73ABD40E34CFC59F96DCE77E170C84849F830181ABC8836882A46C9CE6E46C8F54B826DD2606DC209F8BD5C12402CE38B6A4C20AFEF864550011EE6D9FE2B7E3BB1895670834A02D44ED4911F4C8688CBABF24CA3B3A39618AC21BBC0F29BF46DC8A29B8F9552C3585D004AFA17E0C4FA061172C2FB313C5233705103A97F48A328489E7CA1FE896762C826A8BE58791D59F8890CA2925C75FB00344F8B08D12574D81820C58EE960D8F8BBA1A3A8420612453594B282FD0FF02EEFDB3EDB2F80517DF1E4CD665909A66CA7DB97FB07FBB749A08A547391804E1F010ACFDCD729CF421AAB6F4BEA4186BE92E91A8A4FDF53D5C60C670D37D090300C699B95C951559BAEE7695EF9A7E3A846A91986FAC3DFFE2733A297B437A303E43189169039454CF6064577A6109EC807E8D578AD8DC151763856F9E8494310E52580E6C3D13C0B7C3397E2FDFAE8CF43121EB94303607DE01FD0F648CA +ss = 436AEEE24290F4A1117A9A52451BE197BFEAFF56944CE8C67F783C1482F5C6F6 + +count = 69 +seed = 6D5A7CC326ECF3983C4E7683F45263A37F692F3BCD2D920E1FD9584350119E74F9A3F905F70D3E20318C1413DE2A0DEA +pk = 73D3FD45017EEDA417CD1FE4CE05E76E392EDCE7DF4C68ADE71104AF634E0036D0E999BBF9AB5C3821A1C256E106EDB5BF1015477EA043492ACDE9254CD0E8ED1D84AD37DE2CBF54CFC8D88AC24673086232F854AF9BAA8AB331664BC9137C5F6A7610604DB88E02E1DEC3FF12B66BB975C82135E6E16AE2502269A77BC92526E5CDB585121818E8AC67FFBF0CBD78E2BF3236CBA01ADFB27240DE5C1B26EAEA502877C57D8D771CDE12D268ABFAF9742AE4A54CBD5E0B8D03D1A156EB24DAFA268A21CD79C5AC42510447C86DE0C793060562C2FA4D1513A5716F275D81ADDE59B55D7466AB4BF6754C766477F798BC8EE7532EC734D57E756C42FD3F9F95BA48838B46865ED20C4C529652032D25EB2310943DBF84921E110057BFDD5EC2B5DF8A4E5DC32384792911E93A5BC33A1D68946F48EA192656E77F96B62059DD1091F47FA3B2EE1AFC4127B474091F86848057EDD495FDC0BFC878204480ACA9072610F932F55BDD4EB18EBFEBF0C04AC3F2BA670840758D159396D0B5AEEFCC579BD171FB46285F41CAA45BFB059ED5A9FE2E1A78370ED18BF9E9E22B3345BE10C153EB950295F74231B0E649A51F7CD28325C735869EA08CAC7CA58A0D2AA495E08D8CAC2D1B694B2F46E7AB48B1FC8794AB5F016834283B869EF6D2C88B92E7D5EFC0992BD1DD9C9D3D10AFC9ED039A6952BB1B97342E51062343195581CF1EE64A89A1568CEBCD1A5E693F08CA5761CCCE988E2543B8573C852F76187C4EB36965374C32F9B07BFF9AD1CE58035C3A4EF66C10 +sk = 995EFF7E0D195C6D0533F3DC194D47E60F9AD14696144CDE694D60A95F3E96B4B28F7E7A15A005F92400CE33DB073D49B53871594A88FC45E0F94207B5F0F2DCF1C724CFFE8D40195AEAAE0FBC78840373D3FD45017EEDA417CD1FE4CE05E76E392EDCE7DF4C68ADE71104AF634E0036D0E999BBF9AB5C3821A1C256E106EDB5BF1015477EA043492ACDE9254CD0E8ED1D84AD37DE2CBF54CFC8D88AC24673086232F854AF9BAA8AB331664BC9137C5F6A7610604DB88E02E1DEC3FF12B66BB975C82135E6E16AE2502269A77BC92526E5CDB585121818E8AC67FFBF0CBD78E2BF3236CBA01ADFB27240DE5C1B26EAEA502877C57D8D771CDE12D268ABFAF9742AE4A54CBD5E0B8D03D1A156EB24DAFA268A21CD79C5AC42510447C86DE0C793060562C2FA4D1513A5716F275D81ADDE59B55D7466AB4BF6754C766477F798BC8EE7532EC734D57E756C42FD3F9F95BA48838B46865ED20C4C529652032D25EB2310943DBF84921E110057BFDD5EC2B5DF8A4E5DC32384792911E93A5BC33A1D68946F48EA192656E77F96B62059DD1091F47FA3B2EE1AFC4127B474091F86848057EDD495FDC0BFC878204480ACA9072610F932F55BDD4EB18EBFEBF0C04AC3F2BA670840758D159396D0B5AEEFCC579BD171FB46285F41CAA45BFB059ED5A9FE2E1A78370ED18BF9E9E22B3345BE10C153EB950295F74231B0E649A51F7CD28325C735869EA08CAC7CA58A0D2AA495E08D8CAC2D1B694B2F46E7AB48B1FC8794AB5F016834283B869EF6D2C88B92E7D5EFC0992BD1DD9C9D3D10AFC9ED039A6952BB1B97342E51062343195581CF1EE64A89A1568CEBCD1A5E693F08CA5761CCCE988E2543B8573C852F76187C4EB36965374C32F9B07BFF9AD1CE58035C3A4EF66C10 +ct = 6243F155039B41041E92BEB49E60AF4A869D11D1D9D5D17A63C7B51FF7263DCEF1211976904649482E3506D7B8BBFD88006C29E0A02B1D8C726B4B687D7CFB25A27DFFAAE4AC6E22AF546A6C805293CA760B92736E8C40E3AC66A57E0C3F434B262C90AE9807FBEFEBA00C35E5889E69B9304B222FA4CB78166D0F404B50D97FC69656D525365F94E6E76106721DEBA836DFB2EA7BA89C94F1E6BA70BC2F2B7A32F1DD3B7653EDE1F659DD05D7D3CFE1DD39749B79CDD65966899D5DD675EDD544EF30EDDE569DC421E41537A077437B519FA3A039CA1421DBC29515F33EEDD553A402D4B27F98934693CC155333CD8B3BF3468FEB3D03B4C5F2BACCE0DF7541569BDD7707E613660D2AB247DBEA61F89ED9D9797F4983D8ED52DF88F658140A9E8E03DDC10937950876B242640AD0E66BDBA978F2C6190B64BD5ABEBD656CEFCE32A76506F434BDD46904A10069DF89AD25F96AA1BD3AC97598DA3094CB436DF6B5D2CFD6EE9611C521E77D6370F63CC68E1569576A18290BE837D1D443DAD5FA22E80182B1B420858BA1C23936A63BF2B94FA3C05A0CB7FAD4AFE9361EA593C4160BAF5164B405C16425C1C48195B69D927DC3B76D3C9E3D580353C380F2EC3775D913139425E5B4BFD9A5F3EE0AF9AF1631BBCE194F366C88D3D95F986F0E4C87297D4219494383F842AAFBCED31E22A345308CB9D7A9810BF094B94567314052120B2665484F308FA9751E2FF0CDE7BBD1715537D391F9AA738E0E0211D1280CCA920E23F9F6B9BDC819545A60D8E2FB79123FAA4F34BB542B649C8AAB3BBF13680470C62F0CC9D6707EB76F1900198A8A52 +ss = 5DDE361F4EEA78A44F19ED387F5548126E26E35AE403F3A42A695817EA665D59 + +count = 70 +seed = F68FC0314DEA88F66AFAA76E6C9B6804B13D4876924410D1F526FAC59A62E26C560B125B1D0F8B461F1FC2E351EFFB4F +pk = 5EF6DC358AF8A72280930D1DA2BE63E18AA7E2806302ED77F7D5BB13941C82C8A1A26A899BAFE62E542A0F06DBDBCAC759AAD11285C4C7C4B05022B89B099090654802D40CA7185437A42A7EEAB66FABE44DD2ECDB3655D40F4347A6375FE67A35D1B04BED6EC2C05655B35FE576446E1B5F256AC7F1A1BD6124E8523D2E6162D25E931E3CD00559903410FF1E7ACA06D083E70767871DFFFFE1030F4CD2B8A008981059C776ACDF82668FEA1246F279C002E58B4709653B9A840E0554301F8C219CB994FA1E216044D4117254AA263C6B6F417E5A947D5B5C3C9FE6BC804E8D5D4897FF1FD5087E40CD72DB8057B536D48A6EFB7262A8E194C34E46FA82D2FB99206294EFBF2F6D3AFC3380A19F8A360A708911DFA2A66767324827B217A9BCDC3BD91701F74A1C7DBD100D94D5CFA0F7D7E2996368BFB51AD25CF989882DA4BFAA66666A6BF764CC38DE795BA33251DA7946C2ED64ECB3711AC78CD6BA7B1C8863B9B69F61A3DD4374936A6E9D285F2EAC953D0D2633349971FA1B8D554F07F12BF61BFDD7AD2A5728D830C6C617EE272A12A6B56820B208E90D14972E6903861612DB8B11E18806C42F1FBAAE2E3AEEA9662CBE3924B974FF4F16E115DB0D9B34B10404D88908B98180EC8A9348597D436B003526D609366C95026D19F5DA0CE6929A547479C07958215370F4893C7B7568E95C68ACE58BC8C95C8445FD0CC1BBAEDF1B2334924990F6CA97D5BDCA168C1F75094B1ADE20D4CD9627F408F7536314CAE52E63E13CE775E0B1B176B50A86DB61 +sk = 3E809EC8DD0FEC0D911A4E3FAC20F70FBB128C5DE94DC7184CA7310AE9157A98D8128601C28B1DEF8D393A0DB283229F7C7383152A814E7CEFE8EF9D9768C473AD3022B265A1EA4CB233CAB79A52FB025EF6DC358AF8A72280930D1DA2BE63E18AA7E2806302ED77F7D5BB13941C82C8A1A26A899BAFE62E542A0F06DBDBCAC759AAD11285C4C7C4B05022B89B099090654802D40CA7185437A42A7EEAB66FABE44DD2ECDB3655D40F4347A6375FE67A35D1B04BED6EC2C05655B35FE576446E1B5F256AC7F1A1BD6124E8523D2E6162D25E931E3CD00559903410FF1E7ACA06D083E70767871DFFFFE1030F4CD2B8A008981059C776ACDF82668FEA1246F279C002E58B4709653B9A840E0554301F8C219CB994FA1E216044D4117254AA263C6B6F417E5A947D5B5C3C9FE6BC804E8D5D4897FF1FD5087E40CD72DB8057B536D48A6EFB7262A8E194C34E46FA82D2FB99206294EFBF2F6D3AFC3380A19F8A360A708911DFA2A66767324827B217A9BCDC3BD91701F74A1C7DBD100D94D5CFA0F7D7E2996368BFB51AD25CF989882DA4BFAA66666A6BF764CC38DE795BA33251DA7946C2ED64ECB3711AC78CD6BA7B1C8863B9B69F61A3DD4374936A6E9D285F2EAC953D0D2633349971FA1B8D554F07F12BF61BFDD7AD2A5728D830C6C617EE272A12A6B56820B208E90D14972E6903861612DB8B11E18806C42F1FBAAE2E3AEEA9662CBE3924B974FF4F16E115DB0D9B34B10404D88908B98180EC8A9348597D436B003526D609366C95026D19F5DA0CE6929A547479C07958215370F4893C7B7568E95C68ACE58BC8C95C8445FD0CC1BBAEDF1B2334924990F6CA97D5BDCA168C1F75094B1ADE20D4CD9627F408F7536314CAE52E63E13CE775E0B1B176B50A86DB61 +ct = 69AB14D607EEE5F4CBA5F924578DDC951CB269E1EC70A7C26A9FB6E9F4A5C455D611E67F6F979986945E3A6B7C735194AF0962CC88C54943F8222D36C8E0CB273D859FB33C302F17417BAB7D70B680B5230F6520AA7D6ADD8FE7D4F2DE0B8C4ECBC4387779F789BDA78CBB9E6B073EDDCEFB588AF9C1F9C4ACCF87A052413180446550BF1BC2A7C3597001AC51D23DD937032AB47D7906561E62AB55F08377C189FA389E329B653716B99D0D78BA28CE13471DEC54EB73208E94D23DD8E2D2CCAABAC399E8D2274E2D8919450453CE27AA6482E69744EC4940E6237DDB81DC326F64229BB84D0B15A0012C381E0C6FA9F732319403F76CC8CBF90A862BA4A9740744C56B4CCE1CC7F2E6B6C9AB9A4DF5BD04421F8870EB551B615C9363334E11E8B9617033712F2A2E0F14A9045EE06AF4479E2D3C66B4EED9DC1FEDD1241483FD8BEC5330632EF6F9C6E096CEDC3F86648342C7F17369E2FD7623A8A3175B5AEC240B36FDAE7FDBE9D66FDA69136FE65A73FB72A2B29F2AD179F5EFA3CF45BAE5061C651A573E8F6B711043194F378DDAEB17E8A022C80BA1A93D0F4C77A95EB437FB481289FFBA4C705C78B79AEEE7BD318B5E1D2462602A116C6D9CFCBA95939D8D95519F5FA3AC84BC47A0A6E257876A2B769638DD1C7686F3A88B551438D9CC6E4B5652F3E3F59E563EE301832DDF818017ECC9F1669A16B22DCB629142413689AB6C9DA7323A492636CAFF847FD94DFFA7042D0343A046DE6BB2276C5254244248A8EDFB4F979FD39B3B26B01ACC1FD7622AD2A6081BFA476A8F4B7DE2C163C26434A539078DC0AAA9E2586E18FAB30928 +ss = BBBEE89DF51764C8983ED543DD446DB770B9B64ACDDA2F974A469846744DAC13 + +count = 71 +seed = A229218B0D51F58D915DF549901548FB0722F352C7470900E7E4D8399205764A319BBDDBD06C00E8C5932722EE5A404D +pk = 0C0F2801F17395003FC1EA04C64A485014709E717A5EF620984DFEFBB9DF1FF33A6D477CF3B190D401BC4B9D0CDBC106367A30AF738E5B90E91700CF11D0F30C27AA41DAA2D95D2FA767AD1F834427C87FD1659D4F5E991737BF92C4A41CAA14CA91664E4A15754C515EB584E96F4FC3DB61CA7DFD224A43A482063B8805F8E9BAE4B0CAF1C5A3960B636F8C1DBA63947D3EBB2A38E146D43FEE18DAB828E3DAFC64E09F06AD9BDF1DDB2CC6580DC0B6C954BD4C9E2960888EA12103F22070382C74F5248678E876D6BA614B19692832A1F584746FA58F7CF11A2CBDFF300BAC69C520B579157B449F154D7A27ECAD9D0340C68FC5944779051E01762E94FC2A42A2F31E84517C632A62EADA33CA35EA3F777A3956EA601E3D31F7FEC92EDD683BCCC700EA66B38F23DC72DE1EC564E9770EFCD2BC23EBA877AB0A8ECBBB78A4B4056F62AF26B780A72B58C1E61554C9539DABA87DEB6926CCFA1C629272BF8DF5FD9E70B311B651FC1836ADED5F6638A151D3A3962A955136F821F0B8029913AF26A5CCB5A7BC7C885B02F1C8A0E94113EED2E25A954E87662FFA25CED2C8873123BF49CBA4F63F156404869FC5F986F24C69A9752937871675786CEF02B36CE71754F940B0AD39F5C7E5FDA7963F7B8615107B7A228312F0423E6372BB690F4FBFF61067112F55DDD783460AEA3141A958F7AD747DAFA4573A2A8ACC344F5AF7700BC6BE23033DD32E73F1565FD2C7006C4DE5B9AE7242A07500077075DCA4BE8350FC83D539AEDC8942830945E5F8A28ACE33 +sk = DBF1C465FFF3D9F783BD9EE61A573715E45691147B8904439B5FFAA64F94FF7BB6D75EAC6C76CED1B0A025B40A55440712AD8424672E761E9BC400D63812006F2EA0901B47297BFEDCEEF84A39C62A000C0F2801F17395003FC1EA04C64A485014709E717A5EF620984DFEFBB9DF1FF33A6D477CF3B190D401BC4B9D0CDBC106367A30AF738E5B90E91700CF11D0F30C27AA41DAA2D95D2FA767AD1F834427C87FD1659D4F5E991737BF92C4A41CAA14CA91664E4A15754C515EB584E96F4FC3DB61CA7DFD224A43A482063B8805F8E9BAE4B0CAF1C5A3960B636F8C1DBA63947D3EBB2A38E146D43FEE18DAB828E3DAFC64E09F06AD9BDF1DDB2CC6580DC0B6C954BD4C9E2960888EA12103F22070382C74F5248678E876D6BA614B19692832A1F584746FA58F7CF11A2CBDFF300BAC69C520B579157B449F154D7A27ECAD9D0340C68FC5944779051E01762E94FC2A42A2F31E84517C632A62EADA33CA35EA3F777A3956EA601E3D31F7FEC92EDD683BCCC700EA66B38F23DC72DE1EC564E9770EFCD2BC23EBA877AB0A8ECBBB78A4B4056F62AF26B780A72B58C1E61554C9539DABA87DEB6926CCFA1C629272BF8DF5FD9E70B311B651FC1836ADED5F6638A151D3A3962A955136F821F0B8029913AF26A5CCB5A7BC7C885B02F1C8A0E94113EED2E25A954E87662FFA25CED2C8873123BF49CBA4F63F156404869FC5F986F24C69A9752937871675786CEF02B36CE71754F940B0AD39F5C7E5FDA7963F7B8615107B7A228312F0423E6372BB690F4FBFF61067112F55DDD783460AEA3141A958F7AD747DAFA4573A2A8ACC344F5AF7700BC6BE23033DD32E73F1565FD2C7006C4DE5B9AE7242A07500077075DCA4BE8350FC83D539AEDC8942830945E5F8A28ACE33 +ct = 6C6728D8F7B59D123A44F645504974C45D866C9B0B415A1184D7176D7B68D0C039A54C538741D7444B4F9D50200F16075FAE2EDC78630179021A8E6EFAE58A3DDFDBE59156AFF1A0F3BCBA0BD9BB6C2F05916698DD919CFEBD26A06DEC5C1BFD1732B5EC5F32390EE6F51A84E617B64E8D3ED012E72621CF5B3EB8DD4EAD1EB5E8144B80936201470B64C4B7296896637D62D780917E3C13E2E6C9F472C3A99BB3C9A2962464C5C6204C8ECA3CE92706B30227B60377555A1C67A13D5927B419D5AE176FCA9F98B5CBA7AEDAD616B608D2B2871D09E79CB5A5FA7DA96CCAEA27223252FF976FBC6720F38E54A21A6A2522316C5835CDFF0BB1B8AEB8DB9EC26BDD4C265C57670AD4C1645DAD2A8C2F323EDD5BAE4E0B5B7B634B21044DF166CBF0525CAA1BDC94F49E3ED9F815714C845B89FC614B6B7237F7E19192BC776574F426BE416A33ED17D6B95CAD78C944E3AAEBEE4252A117D1C0B597C5966B88EBDF2EC243423029BCB1CD9F828AA81613F11FFC9EF37D6F1A68A81B38BFF55BB5B07882E3FC37F658D115D0ADF6863EF760BB9B354833DBCFB634740FDF7EEB065A89F3BAF4A7EC34AE2C7A102C482D19627DDD9FD4A86B9C93415FF6A305C4F080D4A9772AB0933DB581A6F9BF1305CD382E3BE3A75FFBDBE714892AA5E58B8BC5BE82CCD7A7023A4BE7B76F602FDE6BDDF2FEE553E0B0A4F4ACDF70E76F737C6A9F3B0E98EEBB14447FBD579C6C7F31D9B79888015529855BA106DCAB5666DA85B4CD801560DC4E9AC985ACFA4689CB6606D46497D8E7E748E78AED101878A9D0365952DCA7A38D97E334D1AA6C109F8CAFF2CA +ss = A16B54DCCACC968F4A80AD53A969A20C5850E04719C28A07C25ADC6F3EA77D91 + +count = 72 +seed = 6960F21C7350DCF41B4770C551DC8692D8BA2C0B6E162C589166FF22E7A1AC0F94C2F48504A5F7EB0DA094DF427BC98A +pk = FFE009C22AAEE7E82FE604F67CD0E4C1D73DB768FCF60357106BDCF6A04B8CB3266BEA47E9615EEB91A19F833A4B1BFA1CF6DF6354433B0C88E3D9762CECDA34003CD4295E39089EFE26D2DC91E3F4DD40B83171C8562CDE03BAF2A6FA29CD90BED721B5E01B0209E56E351F181A44008C4D635187538DC2514C00058C71A243C3C16DD9CA5FB212B192163215B80C93BF27D6312F930A40BA35656C6658BD0DAA7CB5C3A8CE62A8D452A05B117E7D30C46D1B597209D7619FB9FD214A0C72AA40044C2364EF9FC20F64F7DB7BB0AC570F6F3CF011551447A95D798A8F64A7B0CE48EBA3558AFA0388897CF54DF94BFBE9BE82D8E35FA7769DA128EFF348C283D9944A2496E16522262B30030990668ECE04C9D92AAD68F35E6E5DFC6B8E695703A537A0880D5CF02371E1B921B7315FC239E1CA8D2CDEFCDE8B8EF530398D9A61E49942CC6437FDEB11491EE06198C7C8371608536FC9A6D1238040F24FC24C8313AF17877D66818C549FC0DA630BE16CE4C103D1F68B29AB107F5547D4F8E4ED581D0388241CAAF3770E67E7273C9B911A935931E65B62A7290C87A0A32BDF02D41490942AEE8A73489C8CB6C2462714BC6C4BFFA4045215FCE3A18E550E9232AE394F3383B6FCFA767A9B82D7A1A17ECE487FCA660913BD5B252EF9B381F5F7B77C7FA00C49BCBA9521D92EF5E0C188005B8EB2721C453E0ADACB9AB76591C597BDADA3DBDEF4FD804818F3465E949BBDE0DB53985D24BEF15897248A6932D57FEBA9B0D8E03280D857A7F6206F417C7E910E +sk = 1F7CFD2B70863154E8A69D1758532E86C20CFC763D67C758BD10A13B24E759B5273B38BDDC18488024EC90E62A4110129A42A16D2A93C45439888E76008604C611BEBAEAE425BF69BB34B06612A03502FFE009C22AAEE7E82FE604F67CD0E4C1D73DB768FCF60357106BDCF6A04B8CB3266BEA47E9615EEB91A19F833A4B1BFA1CF6DF6354433B0C88E3D9762CECDA34003CD4295E39089EFE26D2DC91E3F4DD40B83171C8562CDE03BAF2A6FA29CD90BED721B5E01B0209E56E351F181A44008C4D635187538DC2514C00058C71A243C3C16DD9CA5FB212B192163215B80C93BF27D6312F930A40BA35656C6658BD0DAA7CB5C3A8CE62A8D452A05B117E7D30C46D1B597209D7619FB9FD214A0C72AA40044C2364EF9FC20F64F7DB7BB0AC570F6F3CF011551447A95D798A8F64A7B0CE48EBA3558AFA0388897CF54DF94BFBE9BE82D8E35FA7769DA128EFF348C283D9944A2496E16522262B30030990668ECE04C9D92AAD68F35E6E5DFC6B8E695703A537A0880D5CF02371E1B921B7315FC239E1CA8D2CDEFCDE8B8EF530398D9A61E49942CC6437FDEB11491EE06198C7C8371608536FC9A6D1238040F24FC24C8313AF17877D66818C549FC0DA630BE16CE4C103D1F68B29AB107F5547D4F8E4ED581D0388241CAAF3770E67E7273C9B911A935931E65B62A7290C87A0A32BDF02D41490942AEE8A73489C8CB6C2462714BC6C4BFFA4045215FCE3A18E550E9232AE394F3383B6FCFA767A9B82D7A1A17ECE487FCA660913BD5B252EF9B381F5F7B77C7FA00C49BCBA9521D92EF5E0C188005B8EB2721C453E0ADACB9AB76591C597BDADA3DBDEF4FD804818F3465E949BBDE0DB53985D24BEF15897248A6932D57FEBA9B0D8E03280D857A7F6206F417C7E910E +ct = 1937DFD660515A2FF1F3CB359207C168A2582393659926955C68E0A6E2482838744E676F823150A6F448D3E2DD62039AF6DF0A21D49C02FCE27AD36EB1B44338F2492F26FE62F4792EFDE28AAE6A6B1E720859EA7E564C41E4496C7D6E57747D851F13FB66206BE2414668E829B9993D5F07C555BBE437828B605A36D25670DD956B19AC1863109721E21CF8AAE054DD1050C12C71F7BF7C142F5481730A94DB5CF17543BB345C0F35AB237C0018A2F5E42B623B914677109F8514331A82C7732CE2B163A73CCDED29AE5374D39AB962C890A9A139E108AB32C7B5476C8058E960B4BAC43FD7251AEC18D21D98504DF4012F12ED3E0790822C5463769A4910EB55D66788F8617E19E5A90C691097372913481B4AE53DD782C326A1F9E20E15092F7CACF38E8546C860311CD09754071FE22EAD8E01FE666F5E7779AF47F350CA19A39DA58A3C538BEBD826583779CB60B64D97E8D0A5F04AA764BBD78F293E0DA2484761D29A6454B87901211144B55790571AF7BE6F1A1351CC554F3FA82A5FF48B2C67E69A2CA7064B890DE23E92BE5A509331D8A9BB8E2C0548BB2F76C4BD8DA3068B6BE6E2F841F166A797C819980C72784F3158E5021E9295423472E5A70AC79CB4F4529CC238DD315FB3EC797811817C7F024A1FEF209FF3FFF831E61DA06BF48E2BA03E3F949346FD7A85F652635F014297B1C0DAA28CA4AED41EA6AD4B050F1D387B46ADD1C14AB0AFFAAF6B44323B362FFC2AD89964AB83D247A191943C8FEDCC231898BCBA91B11ABCBEFB0202BC57218BC6A9CD313765CDA7673BEE784BE6D5DA439DAAC812DB34902F0D25DF8A46 +ss = 8CB2314A3D7B8BCBD157E04D0907A2EA79512BBFDE626433B4977E3C79C26D79 + +count = 73 +seed = 53DF46012CAD4A745B7A3C06E18CA95E0B839FD8161E3025749A0887549EB0ED6A44EEEA08BD6060D6509DBF7E9DC864 +pk = 49AE457BBBEA8BD72ADB129FC56248691C7A4A9C575E24C62C20A0AD79ABD194B40E0B49BD305CD055480450CEDA5144EA67506FB3B729986C4C5BC7DC4478C8A100C3224A454892B3C1B8ED2FDC950D644B0D96DDA9D879F7C23FC40262B7B3FB76497017A6061D4A93975E9FEE9AA7F71D1E14F71FD5FB5EA69FBEDC9591EB3351A6DD13D13CCD1BE274A2CD59670A23B28CD6D59E3B8F81D4945E8F9A252A33DA4976376667D6B1F933729A83322A3CB0C8E77CFDF003948BF15220248478F86A4378D4F7DB9DA407F65BD5C31E7B9ED77D0A05D56CCCAB332B413F90556EC20553E6DDC59A4107AE093337362229462BD7B38DCEC6D5823170A982E326F47D60FF6F614A4A3D69D8893A8EB9CC942999DB2FB8CE5BC2DB4F5ACB683A5684C681F38B11716DAB8605CC769E832C70ED20F40AE86AA717F3DF93CE2B3CC9B7C44A61D336082F477CB425206F8D161147C65FE61360FD595D3457ACF8756885FCB96593EBE1B95F444BC141F32F80A9503483E884CAAB0BCB3630066BBA7B721B4B72E5617347CF17FCE412051574041D0479FC572F4BD2135957A0F4D605C001BA281A7683CCEB6D51173AE6DB38C27A7E9521ACFEF8EA1F615A0BE87D650A39DE2F8128B41FA73DAE30C4DAA0138D955FB713C80C5DD43990E9B49068A9ADCEE40CB6E0B5F3390BF4CAF422B1CBD90B352624BE0EB3416DFFBC1FCCCF2CAD3C5CB1008E6C2C6E29C328F5B754FD76B5D0C7495A23F662D9E9C796DEA43C209E2E831898FDD1492AE0AA90A10E4965C699E63E +sk = 3A19577908EFD37697B8EDC7FDAF47D1BD3AD01A1B77FAF794BEE5B9C3192A6FA3729672816F3EBA84C9638A79676EEAC0F22C8A48E0C5D50A26FF0844C66B9970C30607EDC2CA4DB2912A5DBB81690049AE457BBBEA8BD72ADB129FC56248691C7A4A9C575E24C62C20A0AD79ABD194B40E0B49BD305CD055480450CEDA5144EA67506FB3B729986C4C5BC7DC4478C8A100C3224A454892B3C1B8ED2FDC950D644B0D96DDA9D879F7C23FC40262B7B3FB76497017A6061D4A93975E9FEE9AA7F71D1E14F71FD5FB5EA69FBEDC9591EB3351A6DD13D13CCD1BE274A2CD59670A23B28CD6D59E3B8F81D4945E8F9A252A33DA4976376667D6B1F933729A83322A3CB0C8E77CFDF003948BF15220248478F86A4378D4F7DB9DA407F65BD5C31E7B9ED77D0A05D56CCCAB332B413F90556EC20553E6DDC59A4107AE093337362229462BD7B38DCEC6D5823170A982E326F47D60FF6F614A4A3D69D8893A8EB9CC942999DB2FB8CE5BC2DB4F5ACB683A5684C681F38B11716DAB8605CC769E832C70ED20F40AE86AA717F3DF93CE2B3CC9B7C44A61D336082F477CB425206F8D161147C65FE61360FD595D3457ACF8756885FCB96593EBE1B95F444BC141F32F80A9503483E884CAAB0BCB3630066BBA7B721B4B72E5617347CF17FCE412051574041D0479FC572F4BD2135957A0F4D605C001BA281A7683CCEB6D51173AE6DB38C27A7E9521ACFEF8EA1F615A0BE87D650A39DE2F8128B41FA73DAE30C4DAA0138D955FB713C80C5DD43990E9B49068A9ADCEE40CB6E0B5F3390BF4CAF422B1CBD90B352624BE0EB3416DFFBC1FCCCF2CAD3C5CB1008E6C2C6E29C328F5B754FD76B5D0C7495A23F662D9E9C796DEA43C209E2E831898FDD1492AE0AA90A10E4965C699E63E +ct = F20D4ED0A2553FC72D8C76C5C7DF62B7F75A9BD16381393A08B921CC892B91D8C78F44C8EB56C8BCEDD6B7EC9B0C5996E8A5EDA3020274B604BCEC439C098ACC73471BA3862003A42CCDBD1D6071AB54E4724E75FC0F86403543FCA78C40EC62CC5D9B42CCA92FD556CD976579D9721AD5FD6607921602B8649CA05FB274EBDEBBECF7E99C9DA079D17687DDD72889C4626B34564723DE80434FF59A516DCE80B6BEFB72F70DED9FF6965C88FAAB515B1F1C042453B44E96BC2A826AB3D015C07FF1F22943C390E76194A29582491CE87272DC488F5F200FAC8D0182D333E168549EC4DAAE0922C1D357AD708C1E7554A08B26B4D7E80B91481E4BBC9438325960048E33B1039D300CC26E3C429E78EABB21C95818E09BB57D01F562A55C3829D5BDE3F4CE6440D1DD315F29BE0259563B527190F5AE127EE2525040BD0B8FA7CD33057C45C21CD5CCCF4CA8A66E6A3B1387CB3F3912A8FC75975348D4B67E7CE6F8188696A65EA7E7867721046A30505039D46341A7E20CCA695AD557D4A1399209354BABD2FB7DAACE71973DCB96021A08F865673A4175456E56DF4E18D37A04B1191D134860BDFD92516547CFB3CAFDDF2C1829D8F0A6EC94BD7154E120828BC9E78358D460A06647E61997E0F8BD70CFCC78CC0AD6C4CC98538167FDBC36DD56E1B2D3A10290FE623FA7DF902A9F48139BDDD0481B4D7BB0063B005DCA2BD35CD9B5307960BC651AABFFA84C9DB5133988A8894663D3AC3BDD61D8F1D66E637C5078959FB224376201E67D9BCFE9B8CEEA389008F2EDCE4AB2C705C60F49983B0B381E1037173DF27466A7627C9942B272A6 +ss = 3BC6E89EB86810163951340118ED66AD0B8B84EA6021DF32384D9EE2ED438716 + +count = 74 +seed = DEB963F8B1D8FBDF499D564BA8D2D47915BB402DA02F17031B37B4039A842AFB9B7E48F37200605992BD2429427A7A4E +pk = 05951FFF0481D50C64B950DEBEC328FA03BC56160E337249E40085CA62463297285326C04CA1329498D9E8C64C285892431C0885426AC0072D19F6E0536FB458C4A7C8E78783DE18B2B023F86B8A9B654393F367CF7BA6CCB70853C6A811522E9DE23FD1AB771DE47AEDBA45FC5254BBFC6E8C3996CF07DF51B6859C8728252D0A0E8BEFCB50E70812B7151A45C5FACEF1192D587C104530C47123C7E3C2AC835CD84CD0B55F520C2A94A32892CCEF5F899C8CBA869D23215F278D0AC256BAF2712733EAC7C5AF7C3DA8A1763ECC1280A7BB8D7B753945A6C8C7C943AF6BCB59AA65330E2985587159836623FEB4F77D85455E6AD247877A37004C8A7771E1AF652A661309176F36B32375059C62828DF7734C1ED6C1CB6BE8537B583DB05137545F44B41DB305B32CE983CC06B7D6B0B7AE65B1434CE87CCFC4A6C1CECAFA4A01537BDC7232E42F5AEB256D2356F026826B0B196C409881DBDB2F5EC9708F23EEEA7D6D3F3626E960F9D155AE8071C2C9C5AF40EFF3F746DEA5B6AB572C74AFC35A025C303858428EFCE81190FBBF490C3F9A5119B6965D2E407782E8F56A04E6D5E59F3C04AC3DE8D9342E5F96D5BB5F83298FE9571355EB70F3774BF9BA98D0D76F8D702855F293AEAC144038D92BDA7E9555B9378E48DC890044615C51A03AA81CF22106D50A695CDB2F65A2FC57D131AE93296A6F743CE44DA901DF2441502066D28316B5620518D58460FD80E5768BDB56DED3DEA43783CD26B18BB774DEA9A627AA105C842D7AA36151419877C657E731 +sk = AE0F65E29F38804A6759F70F4D01E2AAFF7FE1C91EBC4F892DD0DE3AB2E68EA5E03FF73E02A217659F53D8C47556BF3D8C94040F630D63605E2D0F923579370C95E08D6CD768BFBCFEE1CB565A2CE80305951FFF0481D50C64B950DEBEC328FA03BC56160E337249E40085CA62463297285326C04CA1329498D9E8C64C285892431C0885426AC0072D19F6E0536FB458C4A7C8E78783DE18B2B023F86B8A9B654393F367CF7BA6CCB70853C6A811522E9DE23FD1AB771DE47AEDBA45FC5254BBFC6E8C3996CF07DF51B6859C8728252D0A0E8BEFCB50E70812B7151A45C5FACEF1192D587C104530C47123C7E3C2AC835CD84CD0B55F520C2A94A32892CCEF5F899C8CBA869D23215F278D0AC256BAF2712733EAC7C5AF7C3DA8A1763ECC1280A7BB8D7B753945A6C8C7C943AF6BCB59AA65330E2985587159836623FEB4F77D85455E6AD247877A37004C8A7771E1AF652A661309176F36B32375059C62828DF7734C1ED6C1CB6BE8537B583DB05137545F44B41DB305B32CE983CC06B7D6B0B7AE65B1434CE87CCFC4A6C1CECAFA4A01537BDC7232E42F5AEB256D2356F026826B0B196C409881DBDB2F5EC9708F23EEEA7D6D3F3626E960F9D155AE8071C2C9C5AF40EFF3F746DEA5B6AB572C74AFC35A025C303858428EFCE81190FBBF490C3F9A5119B6965D2E407782E8F56A04E6D5E59F3C04AC3DE8D9342E5F96D5BB5F83298FE9571355EB70F3774BF9BA98D0D76F8D702855F293AEAC144038D92BDA7E9555B9378E48DC890044615C51A03AA81CF22106D50A695CDB2F65A2FC57D131AE93296A6F743CE44DA901DF2441502066D28316B5620518D58460FD80E5768BDB56DED3DEA43783CD26B18BB774DEA9A627AA105C842D7AA36151419877C657E731 +ct = CCD305E6FE7BDFECBD7898E039D3BA8053FFEF46A7869D249E35500CCFD7B38EAC75B8CEE8AED18B252CB3B2D83AB3C652B73522C47B1119A7B7E0C791F44D847BB8E62DE54AF97B4C56CF0C16C4615858E5D931B0F0B09EA4A48AA81F235FD1B43782B0DB32D645315639951E8E530AD42B274075144FADB6F35F3848EE373198F09C87CD1BFC74DC9264D7F41A29D163A2BB73A1301C0533718EDA9CB5406AE3B6918F9A60E9429361EC7BB4F5D2A4AE3D4A2988BCAAFE2BB72C034E15C8FF341FD3A0938F2A8E65AB9EAB3B7343D94917141ECF3A142A9543BFDE23FCA78C999A01A3BDE43C3740469DB2C47EE85F53062B380C6D19D1B5825CD0D338E570C4157222C0F686E772A394AAE5E35E183B9AF0952712414F6D4328EABDBE04E69C96FB56A34A3778AA130205BCE4F23D3B9A212D1ECCC9BFEA7DA238BA5D8ECC85B2B99EDEA453E8A965F30D69F9AC206DBE00A894B563A1FB4E92977035F35B2E273D598C47B512CA34EB35E9EC1DFE78B9F5F11E68356C0E9C37658464CE599270F68178C1845486871D4E709E1A9672850BB522C3BE6A3C8C5996594663F8436F9252956A7E992C1EDA0EEE7A27AB1BEF236354E958F618B665FB7A4FAFBA1A8BA77CA337ADBCCB985D5E4E8BDF496F6C5F4B1220B2A6DBF2EB27FFF933B98BDA90EEE958A3C3D480B28A32B3AD501B2009F5E016FD31ED4031B34E0B7FE28D95E0A34D32B012AD00CD7E7DD2089F69B6E0E6FD784CA5F332662E9EAF7FFE890261B535035D072D29D38262C4680F6A6B393C2850FABAAE263CA4CB392BC0BADB7017684419952A1D08904D4E692E5522331F +ss = 9C96C97D3032D9A7283A9F4488D291CC7484F8F6DCA8B17419B04DDBFD9A12E1 + +count = 75 +seed = 8E2995F1B3E43853B18916BB1212ACEB05898E2B177A87ABEB928AD7184E59695C56B2CCCF5DB80853C28A525E327D13 +pk = 077E537B7271895348293B7C34EF117FD286DF34F0E07BC89FD344DB8D1E5D8CF0E7D41F1A7C22BE01B3A3AC8FD919C68E936E4F66F543F365E199C41BAA599D49CE23FA772975E225F2AC3969FDFB32BF4A2F26B388E9C51377EB778159112730151F4F3EDF3197713424588F1BB3B2782FFC9200279B11FBEB4D7204C4504C246DA183F1E15B9C7B89B39FCA508755865B8EABF1D363D279B0F38D8CAE0EDA7926F370BC66F67C31BFDB44DC9CF2B28F9DEC21520DE58B8811161BD33E14E41E13EECF0CB587158CC5661BC79B43EF41AF9CB3F6D3A006FACFFED78B2A8BC6CCACC4694B2D470480D698508016333BE798457F632BE1A79AA2ADBB165CC5CD3020A7AAE9FDC2157B6196836D48709E1F0AD5318BD31531450EC3FBDBC1D00286823EB7FD00B08935E2E6CBC1104803D154DFABF848418147F0429B7CF7A3F532917989106E96A7161E3444712AF249216B01D7C2BA97361FF9B3B3518C0D57B5D1A4023F88EF69640E63BABF6DE29536BFE39E4B28CD08CA1AE6C9DFD9D2080DB9A7AABAC74E103F6AEFB7447C36EE43C91F2A8042B96D33F7922543B88D5E8D78D5B9277986A52FFF1C51EF03B33CB7AF137645D78B05F9ABE26EC423472B168ADC67CBDF8777AC8F3EBC2ABAD44F40C03A00F01C8D1B961242D29B70B4C45A32F6D6463C4720F98C7A9C95C74E037E15A22FB769A8D3F45F93687BCAC6493171E15D0E919AADAC8906FF2E80C3212E02CB9041228E4C94F692E266191C16AC895DE4F7045CEDC85F29C41B24A845DB9D4B2A +sk = 6084A235F79DD093EF6D185B54E69DF33DACEE73A9BF2F379004421A10E3A79D9F684FB055ECE19459EB464E91E126A7A6E3ED11CCEE0046DA234D964C9851104A2A81136C9568A90022AD41A5917000077E537B7271895348293B7C34EF117FD286DF34F0E07BC89FD344DB8D1E5D8CF0E7D41F1A7C22BE01B3A3AC8FD919C68E936E4F66F543F365E199C41BAA599D49CE23FA772975E225F2AC3969FDFB32BF4A2F26B388E9C51377EB778159112730151F4F3EDF3197713424588F1BB3B2782FFC9200279B11FBEB4D7204C4504C246DA183F1E15B9C7B89B39FCA508755865B8EABF1D363D279B0F38D8CAE0EDA7926F370BC66F67C31BFDB44DC9CF2B28F9DEC21520DE58B8811161BD33E14E41E13EECF0CB587158CC5661BC79B43EF41AF9CB3F6D3A006FACFFED78B2A8BC6CCACC4694B2D470480D698508016333BE798457F632BE1A79AA2ADBB165CC5CD3020A7AAE9FDC2157B6196836D48709E1F0AD5318BD31531450EC3FBDBC1D00286823EB7FD00B08935E2E6CBC1104803D154DFABF848418147F0429B7CF7A3F532917989106E96A7161E3444712AF249216B01D7C2BA97361FF9B3B3518C0D57B5D1A4023F88EF69640E63BABF6DE29536BFE39E4B28CD08CA1AE6C9DFD9D2080DB9A7AABAC74E103F6AEFB7447C36EE43C91F2A8042B96D33F7922543B88D5E8D78D5B9277986A52FFF1C51EF03B33CB7AF137645D78B05F9ABE26EC423472B168ADC67CBDF8777AC8F3EBC2ABAD44F40C03A00F01C8D1B961242D29B70B4C45A32F6D6463C4720F98C7A9C95C74E037E15A22FB769A8D3F45F93687BCAC6493171E15D0E919AADAC8906FF2E80C3212E02CB9041228E4C94F692E266191C16AC895DE4F7045CEDC85F29C41B24A845DB9D4B2A +ct = 9AE113E28ED739AFA138C9EC05920BEC3DBA0D0C9C3318A045F31B662DF50D46BB45EF3710E5821D29A8CAAEFC723065812A406BCA5342B88CDBA262420AE080BE33686DDAF7588CED0F07CA1823347AA7C8FC2EE7F3923D7AE049460D24E5220784197A27A106E712E47053559CB14110D5A6D136A28ACD5435D6AD63A54A395CA56A0E298552858A75CE5507911160E90C6407BB06539D9936121A560DBD15095AFD10A0687B293E278624E47777670B853AD4981567137F8D1A47FD6D641346DEEC08DD2D6C8BDB8D6D8D7EB1051B79DB6176AD08C10BD19FF0317081709413424C08A36521B0709270030BF7A3F47ED7C102D9AA7FEF25B76CF94C8AFEF4D78600D571C9D1BE6B574DB4DBF6604C1187D64A50123B7C81033C42833CA390B6681F74613627309923B986BF962A1E9D47BFFF645FD35EB63E1C30CA7B6EC15E5FAEBE11BC880521C380B4139A2CF68C00A3A9090B91B467C1CB353FF181DABE590393B84424C1918F7F8835292CE0E582FE16C27CD968ADE59982EDA3D72112138310C0146640EFF9993CF114B04C8938F991A09BE91EE4CD6AD3F49107E31C79FAC5EDDDC54EE253DB3842E68905FE29F031DA3CB1F314F86B85E13FE83956C6F84A8FB794942C9C6128D2CA65200011826EBC6C438D960056D8ACB8BB6481033BCA457EB57AD125ED0353FE1BF128E13ADEFF51FFF97B6D76F6B8841A9FC5CCF951C49B2DB5E79385AD503A31E2ED8A3FD92984838DEFF9850BF704D0AD58CBCE1917E22560C31BF5EE1DF9F69FBE11A0542AC4BB048F3EAD1CB80BD3AF764C02A46765EBCC55750E57CDEA8F9D226AE77C +ss = 2193074EA86C6435F13AAF99E488F9CD34049D64EDE5A0DE7A84F5DB6474CF2D + +count = 76 +seed = 9218943C51FD2DE47E509AAC67EFF176795102F37D7A2017E3AFD768FCDA7877AF38739B00FCDF227C2FD62EB635942C +pk = 9EA31FE59742CC79C94403195F890147200EA340CA264B528229ADD2FD8832047CD50A0966AB788F51734716FFD4E86856B85058089678C6279C3750AECE7A675B0DDF41AEDC25EE035C1E7106A042C2491161CBB31509CDEB640F03C75D4AE90FD4FCB00D3C3C449AF8F3844CFA7471E5F316674A13E5A6A6347FED322C765B568AA6CD175945D20D3F01F3EAB54354B0F5BE9326D3E37EC1D87CC154042B6C0B8E7AA2F5B4AC49F34FE4CF922FC47152CCAED8EACD7FB4EB19656810B0844239D19DC19E920B98ABF6916623C0C31CCAF33B3F18CCCACD5F2CE498511F49F134D297041354EF7093FB720954005C93B27E8AEC1515FC73D463540AA50AD3CC36DF100E10455C1B202CE77CC698A75CD0B78AC9AA0F1E840302D37504610C63157D9036A278E6DEFF535647AC25EC03F864A539F9FB61B19B09FDADA995D5D3127093BDC3E9DDCAA61C75B9DAF354AF079CBB52EF1DA5AC3FA8F05EA90A0F8B979630CED6D365ECD9D60E54CCFC33B859BE5FB59587456DE9DD1E60F898A7958BFC7BC1FFF196539B5EB1958C3D8859B72147095E71DBAA03ECCAA8FAD885437A8A6F5FEA8BE22AF761DB7442DD8CD08B1B1768DA0F5DD99A6D061FED11F6EBC6F1AE7162F16C8D42885D333A0E2340808F877DA023D03A0BEECFAEB110D3921F43013508F8D180DA79E3234D4A7C1D3E3A33482FEB7A7FEDC9255569D14C99C378C5D5271025F0909EFDECD361421268ED53A9A49E7CBD3A4F3775EE66CAF5B1196B8F97AF3DAEC2F8F7F4F55E17776E31596D +sk = ACD1C0217FAD5CAA4235544DD9DE153AB1880CCF4C76F16F236FAE4E4BFDA04CF03A8ABB0A5010F400AE5722A75BDF5A2F6D5B546B34D73857CB1BFC7E587AA73EFECFB5A325BE44FE5C5D3C4062BC039EA31FE59742CC79C94403195F890147200EA340CA264B528229ADD2FD8832047CD50A0966AB788F51734716FFD4E86856B85058089678C6279C3750AECE7A675B0DDF41AEDC25EE035C1E7106A042C2491161CBB31509CDEB640F03C75D4AE90FD4FCB00D3C3C449AF8F3844CFA7471E5F316674A13E5A6A6347FED322C765B568AA6CD175945D20D3F01F3EAB54354B0F5BE9326D3E37EC1D87CC154042B6C0B8E7AA2F5B4AC49F34FE4CF922FC47152CCAED8EACD7FB4EB19656810B0844239D19DC19E920B98ABF6916623C0C31CCAF33B3F18CCCACD5F2CE498511F49F134D297041354EF7093FB720954005C93B27E8AEC1515FC73D463540AA50AD3CC36DF100E10455C1B202CE77CC698A75CD0B78AC9AA0F1E840302D37504610C63157D9036A278E6DEFF535647AC25EC03F864A539F9FB61B19B09FDADA995D5D3127093BDC3E9DDCAA61C75B9DAF354AF079CBB52EF1DA5AC3FA8F05EA90A0F8B979630CED6D365ECD9D60E54CCFC33B859BE5FB59587456DE9DD1E60F898A7958BFC7BC1FFF196539B5EB1958C3D8859B72147095E71DBAA03ECCAA8FAD885437A8A6F5FEA8BE22AF761DB7442DD8CD08B1B1768DA0F5DD99A6D061FED11F6EBC6F1AE7162F16C8D42885D333A0E2340808F877DA023D03A0BEECFAEB110D3921F43013508F8D180DA79E3234D4A7C1D3E3A33482FEB7A7FEDC9255569D14C99C378C5D5271025F0909EFDECD361421268ED53A9A49E7CBD3A4F3775EE66CAF5B1196B8F97AF3DAEC2F8F7F4F55E17776E31596D +ct = A61E87C17BBC3CAE7658A309DE71567B2F798EB97A54B93A0C2C652DE6F7982C9BA99656FF6736665C2094E15BF33A766D7147CC58C6C138AF15F2343AF6F27F81B5F7C44290F511E329E9F92E7C8387329F4AC67A2D0340FAF1DA64B9333C07F74BA82DC5BEB10C97D3BAEDA0F118032753299A35538D404958C209D3991E3968C2403442BA395B2C8F3BD5411DC68F644747D82753BD60E137FB3989E30B1A1D4F98709499E90A3E095E3802868584F6597058E0D21F1D285A491A43AF641654F405C4E76D4E823117A4FB8DA11A37F07072D07D4E9A9094936960A032EC690A01BFA25A18E8FD83342B4E0DE56F6C7C665EBB4F4CDD8C585637D8D127B2ACE477923E0213BE888730FBD6AD071132F358B36CC27DDC55E428C341A66A588FB632A66C1830CAC8BB3279DC1538A4871A7251C6959B3637F4E5D92FC068CF021E4DF203DD9FEA9C2D4F5F8D5CFE310D05E96167DEE1B5EA1B940B2631E58B8F68789B847C06A5788D7C8E722FCD1BB623DA86FB97120916F39CC1EC1BCED05E7E3F0FC090C4B91E38E199E504CBE83F4D470C638D3CF497E8D2DDCFF7F19A03D1A9E60686A9BB105BC86E41C481C4B5F11D9514010C44A278EADD352F0C6E6CC5269BFEB30ADF671B3A3D433B9D69E87BCAF504B43E2B6D072C9D00FE9C19D6D71C0E22E8643F002678FC2BFD67B3001F66EEC1AAD33F4F925E224280D5C400F13DFB2F5137F75E3078051453DD6EEDA78C59874984057DC3B66766D3AB48E4F3AD7FF6FFFDBAFE32E300C926256CDEC010415DC99BF54D653B3BA8CCF3B8C8EF07DDCB59B132FB741DAA5A7C06E43489E81B3C +ss = B22BAE3C5A03DB642A25672388E7735BF8E23AD6814CFA72F7B9E5F62614F7B4 + +count = 77 +seed = 542E20078ADD5296050AF150360F057F6B9AB3BA835589DD56987DE805F900B906505B5390A0D86CBA28038992DFC59A +pk = 49EBB990C7F8408519C13A9C6CEF765C21C156D224C818BF2895E94B55F8806E0339839AB1A8B7A9F8A9CCAD5EBB16650EC8164AFCA022E094E01765FF49DDE35468755EC176EE6D35C692E848975225F22131172E1AECF4F51CABBD3A5CC73B517A61DA7F3466E2F53849B81BB5D6EE2BA91BDABBE6E2B6FA731F40950237FDA8F0205232810813593722270BC1D9180C10E1526BCADF15B30244B216EA5E311DE6F2344FBC85F1CE38A24DE9977441534D2F79B3FA1317CF509C46458EFA7EED6FA51171BEFA4D6946FFA61F091AC3446DFCDB1D9E7C29884E4758F805CFB54FAE8706C9A28A1F76536E1AC9929DCF70A0A59BD2CDB34D0A82E71FB0005EDCE388FB0F8241A9B2200E8CE97C381EF0B9427727A91A5C26B13B95789DC4A002C19FC15B7E7210F5D7CEB4DADE023FE5DE7A70F63218AFB8ACD717AB3D6864C2B773F45C59171D44B48D8662C3981E629286CD2D9C232A0B738B76B616E1BB955DEC5115810BA52C190C21BB02A6FD3F43EEAA713294DB5E58FFCFE6F53601C2F2DB38EC1FD8651DD7ED702B70F6C9375E4C4A51D79E3C0DE28A5B6801AB8F7BCFF099E77672360FE7B1A036B36A7843A14B7F085004C9F83529F448C61AABE105C281F3E504A64BF40E3909B619997B080DBAF3621ADC5B9464BCFDFA850DAB77A3C676D2BB8537EAD3AF16ED2FED11B61846A622AB1A5FD14BBE9C1F5D862BCE653CCF007E552E418C3D9D3B18CBE1AE95E413E032ECED079AD01F98226067D6551DB612DCDF2017D1502D55EB888BD93F1514 +sk = 241191401A63AFA750F05662E354DDDBC683C776CE3222BEB83E3CF913D7ED7CA59B3BD23B49A95BC1FAD20070FEC930B6060BD827D742B077092E422268E15D85112C0C2683DE1DFA7719ED7F49880249EBB990C7F8408519C13A9C6CEF765C21C156D224C818BF2895E94B55F8806E0339839AB1A8B7A9F8A9CCAD5EBB16650EC8164AFCA022E094E01765FF49DDE35468755EC176EE6D35C692E848975225F22131172E1AECF4F51CABBD3A5CC73B517A61DA7F3466E2F53849B81BB5D6EE2BA91BDABBE6E2B6FA731F40950237FDA8F0205232810813593722270BC1D9180C10E1526BCADF15B30244B216EA5E311DE6F2344FBC85F1CE38A24DE9977441534D2F79B3FA1317CF509C46458EFA7EED6FA51171BEFA4D6946FFA61F091AC3446DFCDB1D9E7C29884E4758F805CFB54FAE8706C9A28A1F76536E1AC9929DCF70A0A59BD2CDB34D0A82E71FB0005EDCE388FB0F8241A9B2200E8CE97C381EF0B9427727A91A5C26B13B95789DC4A002C19FC15B7E7210F5D7CEB4DADE023FE5DE7A70F63218AFB8ACD717AB3D6864C2B773F45C59171D44B48D8662C3981E629286CD2D9C232A0B738B76B616E1BB955DEC5115810BA52C190C21BB02A6FD3F43EEAA713294DB5E58FFCFE6F53601C2F2DB38EC1FD8651DD7ED702B70F6C9375E4C4A51D79E3C0DE28A5B6801AB8F7BCFF099E77672360FE7B1A036B36A7843A14B7F085004C9F83529F448C61AABE105C281F3E504A64BF40E3909B619997B080DBAF3621ADC5B9464BCFDFA850DAB77A3C676D2BB8537EAD3AF16ED2FED11B61846A622AB1A5FD14BBE9C1F5D862BCE653CCF007E552E418C3D9D3B18CBE1AE95E413E032ECED079AD01F98226067D6551DB612DCDF2017D1502D55EB888BD93F1514 +ct = 9F4F2652D29424A545B1423EC43166248F49588258F6CF2307D0335D26CF172CF2FE4AA2DC42DDE14E98245D3482C4427E26EB4361C5D2404D2386EF63593FBDC935AC2D4FAA05E23EB8AC0CDA617289F7E3B34AFF9934A3526EB03CA33DF92D02E1C22EFB3C93813EA2F4E9C37935BB2BE85F173EC9AF42CC2198DD94C9B793BFDC30FD13E45E527F66B708E043A08B0E5FFD6F51EC1BC5E151FC4364578FD77E950552C4A9EB93E7BEF5617D9B1AA4A0134BDD353DB14CC3D7032AE512B1EE75FAF0C04C5911F4218B69DF28A8F0051A6041B3A4D9C54B1E3C4052EF71E21F18A3329CBC021D7881D1A284BB8F085B0E2814649D8CA66C1BEE7EECD7A5D3F468D6F64EFB02DBABFB4220B9C8892512FC4772ED64E5732F4C43E481D138C548DDC74900916C2C00DC629ED0E3E096918CC933A4AED2A50793BF189B7F73D3EFC4B206544A10CECC4BA79051475C6285E7A8F6BD1D06756B7F5BA22376E81D3366634DB67D60BE3912024167F257448585D50A16D20CF5368E6CD197022091CD96ABCBA9CF4638D19D9C798C67B33AB0027AEEC25FA303D8B0A8D7AD9563A4A5A6BF7A37DE7307DC23B8777C4899F8713CC2D664761938EAAF6B305B6CD73BEA41502D8FC89017E7F5606DE25549BFC18553F8EDA9690B4AE282B028E4378BACEC6457A99ACA4808D799344A8D339B7A5AEF36227DCF5FF5B3BB95F1E83251AE1B369BDAF153B09FCC607EB98EF4AC4B500FB1A9949797AB80B6B7AEFECA72110A7BFF1F7E43AC7F0DAC9C1A39F40721655B4C699C723B0A21D555BBC92E7D71E51F1638F06C2CDA1206152E42635A7F35A3AEAC +ss = F5ACBF38290E446BE322E745C3E123CE1EF475BD16D450B49F56251633AAD8BC + +count = 78 +seed = 6A85A61DD08C0733FCBC158ABB49FE0B0D96A50DCCA140A2E9F5A254F1901985844613B1C656C0CB0112620591B88AD0 +pk = 04884DEE02F72E43053F7C3F6C7B7561585E66B156C6B5C71719744A750F42628817127798731190A1B877AD85DADD8D3B253C56197885E300D567BD25FA0DCAD6442C2F568E7117A34270648EEBD13A300F9FFA190C79B9282D8DB1EC2B44FA6935DF723A81FE2BCC449C1B30DFC56A49AF13E578B04C6BF8DEABE983C9AB0FFE3CF6A4E06A2C34946431B9B9A2B74AC76017203021F66295177EB5187543981DBB43413A2F25EC2CA8C583004EA2C4F6D5D2CADF8E444797BF0728B450AE24D6E438372756D2F4D6649D099A4A98451B8DA07AC5A86D556AEF8FA3DB557685CD1942637BEE2CCD9E62071004EB8AD4884CA05EA2BE7BD397432D111EEE1D9EF5CCD50DE7A1762764BEE066399BF381F2E24054483A76BBF76ABC06DD0CD3CA052A1C794E1D1DFD40540F34F65286D47DEA0BAD2A688AF3A11262ACA7F51EA413E29BF951EDD7CDEB39BB0A1D831CE87FA2945302E48429B58C7567DBB2D1F4CA0594A64E95E8C8EE35A98DD332C2E25323D5D3F3DCD118EAA178D5FB6DB76C8A24D027FED4B433D9EEAEFA4EA71852C3A023A33BA6C81D03FF89F36A98C8523DAF0163F0B6961378874CA5C98BC4F21286E7F45F9F08024CFE200539F35A83A5966D0FED1485D24A1A2F9FEC7A721507CFA8337B31AB08FD71A2ECA6DD88DB1576751EA028CFD743BEC5D2912B7134B48291EACD7A5E4F5D0660279865A03F636A4E572C85CD24FA78A484802D20C284E41283B8D0F5FB129DC61A30D177491D12724C0ECB1EC57323CF45F53F89FF290FDD53 +sk = B9A6B0C05677E957D41A34BA03BD06F2A9092E31F63389397D7E70FDE6409D18E99C0E7B82BE89BC3C1EAEE6680AA4EFD394E40C2B3F30523C8117F7C26A8969B6E72DE77006189ADF35F4EBE05AB70304884DEE02F72E43053F7C3F6C7B7561585E66B156C6B5C71719744A750F42628817127798731190A1B877AD85DADD8D3B253C56197885E300D567BD25FA0DCAD6442C2F568E7117A34270648EEBD13A300F9FFA190C79B9282D8DB1EC2B44FA6935DF723A81FE2BCC449C1B30DFC56A49AF13E578B04C6BF8DEABE983C9AB0FFE3CF6A4E06A2C34946431B9B9A2B74AC76017203021F66295177EB5187543981DBB43413A2F25EC2CA8C583004EA2C4F6D5D2CADF8E444797BF0728B450AE24D6E438372756D2F4D6649D099A4A98451B8DA07AC5A86D556AEF8FA3DB557685CD1942637BEE2CCD9E62071004EB8AD4884CA05EA2BE7BD397432D111EEE1D9EF5CCD50DE7A1762764BEE066399BF381F2E24054483A76BBF76ABC06DD0CD3CA052A1C794E1D1DFD40540F34F65286D47DEA0BAD2A688AF3A11262ACA7F51EA413E29BF951EDD7CDEB39BB0A1D831CE87FA2945302E48429B58C7567DBB2D1F4CA0594A64E95E8C8EE35A98DD332C2E25323D5D3F3DCD118EAA178D5FB6DB76C8A24D027FED4B433D9EEAEFA4EA71852C3A023A33BA6C81D03FF89F36A98C8523DAF0163F0B6961378874CA5C98BC4F21286E7F45F9F08024CFE200539F35A83A5966D0FED1485D24A1A2F9FEC7A721507CFA8337B31AB08FD71A2ECA6DD88DB1576751EA028CFD743BEC5D2912B7134B48291EACD7A5E4F5D0660279865A03F636A4E572C85CD24FA78A484802D20C284E41283B8D0F5FB129DC61A30D177491D12724C0ECB1EC57323CF45F53F89FF290FDD53 +ct = D91D06FBA88E8F863F2618E29674A68D41555CE672B9197B0AACB0E99B9B93A98383FCEB096BED4C9ABD6BD1FDDC7D7466BD9530DA52912B58BA4E8250619C3FEBF3B0DADBBF04DE892D28330C93C0FEBC4C3CD9CDD2F8BED09379DB80497D279293B4E62E0EDF9DA3FE0CE60A13AD7337FCAA3D788DF1DD80D97B5CCE3DF088FB9799BFCEFD6A526F22A85A3E8DAD55C523CAF3B83E078BF8E959A22F3CF2FEDF18676ACDAA439FBA1095CEA1B882E5F4D89BB169CA24E2B67B372B3924C6911DB502EDDB32B526BE93190C47148B52B58CC32405DAF7C684D7AD9DCDD526638981044D34C8138848B4C251A4D30B04FFE9043C0D605421991793C6F2FB8B31E5CD6134126F205F11CB1EB6FEDFB86C9552791B1DD7AE21C0006E01A0C63565BDFDDA31E76A96AA223FEB1747DBEC5CC733774E248805809FDF0A06CD234CB3C1C70B1EFBC3F0CE26DD4A02CEFF0CA4DD83A52C55A8DCF2F2DAAEA335F191589732E097869AA15D2ED85ECCC641FA419413BEF635D82822AE02E67892BF672223C8CA79B1673F2B9C378E5F99A787A1F2705DD9ECFEE852D05952E16D1F588154B9802910038A7E2A4F9F72708897E2C519B1834D0532823C3FC26B619B3E4C53B8E8F170FBCC0D91283D6680749339CAA56651C56117081A9A0A3EFA4C7A50062B771AE908C7A316E3AEA2FCE9666C39E42EBC8AD67619CAFA0EEFBE29FBA5BB229D4782A0FB55DE6B8E632361AE1BF1B2B446ADF8D7AC0923F949DB4FDDF9486FAD4BF2943E95880C1D259083BE1797DD365E99E4BF89BA2340AF75E992FD65E97A33B24A7A773C1A6F64DF36CD41B7A6302F +ss = E91077A726D3A16BAF511702ECB961A3E5D2102DD9A1C2C21AE8E6C90F2F587C + +count = 79 +seed = 7F4A56EDA151E7B097CFB8EF980440FFF707AFFBA91867C89522CED6C5FF3BD7F5F00BB49DDD615D9361A7E4EFA42851 +pk = 8942F8F7EE31CFB8B10912D2A0BFB2DCB590433AF2CDDD85B10240EC226C23D2A88159687DC7F6B714A79BD439E508E54D044F8728D48CF8F54FB86D1755ECADD4EF4952521670ECE451A4313D13150C1497078BD04EA25F1357D3937D6812EFB62E51F800B09574BA7D8CFA39B72D9AD596D85A04398EA0BD7E2885B06BF5FBF064D9F79443D2D31EAD55E7F6980DA267FC11D1638F63F107A2A6919BAEF35A0C8728924E4344BE6886D6D6EB95E5CA2C105E9CCFD973710EC7054EFC021FEEEFD4F925B7625062471F577ADCB0792ADA632DA45DD33A29032FF1288A66757BC89E7B4C2BB97995D2492EAE03C175A4FADE23904B8A167A0AC5D42BEC2FCD46C61E24B1E06E49FE3407E1626869A48FEA8D38FF16D81DEA901C6749F983687E6327E21F02508D9BDC975CBC85126D7F785278552C8055D49835B3A6BDE4ED9DF73F2A4EE154040607B7D8BBBCBF606D3952EAA8500F77F43894652A6633C70C672AC1B25B7A64939364993FC8D7204884557A77032F675FED86D1B182555C5998B59C91E382F75E00E2152FCEC1CDEFCE421A5979A2C57E827A55536E9C5FE97843484F29A4DDA461CF94E9A8E5CD14D00D3815AE71844B340ECDD58B4AF8E010F1427C2BAE07B61BDC54D28DCD07EB01E94C14405B0DFB052AA5E22412CC1437179AB8BE1C33537385D0584DF3301BC233F7E5FADA9E88DDC7E8AA2334EFD42A46BCB7F6AA0564C538B823D1001ABB2AF715A4D174653D0A49B0DDF822A21747638F6178F42A40284B222C9320B558EE240F12 +sk = 28A96C71577BA00C94F99FE965BC595A26DB2B3CA6AB5CF8E443CDD8462B17929C35D165453E5FCDC6F9DF64526D9DE698F2BD3E6BAC6C7FDD86601B9BA5F4A503F3E68011F266F54BBD60DB0F99BD028942F8F7EE31CFB8B10912D2A0BFB2DCB590433AF2CDDD85B10240EC226C23D2A88159687DC7F6B714A79BD439E508E54D044F8728D48CF8F54FB86D1755ECADD4EF4952521670ECE451A4313D13150C1497078BD04EA25F1357D3937D6812EFB62E51F800B09574BA7D8CFA39B72D9AD596D85A04398EA0BD7E2885B06BF5FBF064D9F79443D2D31EAD55E7F6980DA267FC11D1638F63F107A2A6919BAEF35A0C8728924E4344BE6886D6D6EB95E5CA2C105E9CCFD973710EC7054EFC021FEEEFD4F925B7625062471F577ADCB0792ADA632DA45DD33A29032FF1288A66757BC89E7B4C2BB97995D2492EAE03C175A4FADE23904B8A167A0AC5D42BEC2FCD46C61E24B1E06E49FE3407E1626869A48FEA8D38FF16D81DEA901C6749F983687E6327E21F02508D9BDC975CBC85126D7F785278552C8055D49835B3A6BDE4ED9DF73F2A4EE154040607B7D8BBBCBF606D3952EAA8500F77F43894652A6633C70C672AC1B25B7A64939364993FC8D7204884557A77032F675FED86D1B182555C5998B59C91E382F75E00E2152FCEC1CDEFCE421A5979A2C57E827A55536E9C5FE97843484F29A4DDA461CF94E9A8E5CD14D00D3815AE71844B340ECDD58B4AF8E010F1427C2BAE07B61BDC54D28DCD07EB01E94C14405B0DFB052AA5E22412CC1437179AB8BE1C33537385D0584DF3301BC233F7E5FADA9E88DDC7E8AA2334EFD42A46BCB7F6AA0564C538B823D1001ABB2AF715A4D174653D0A49B0DDF822A21747638F6178F42A40284B222C9320B558EE240F12 +ct = F00C8F436880B2BBDB85BA3B6F8A4942C94D76C6E8B04E784B182E3190364D0103A39C398A3561CC8E05BAF140FC13A317FE8C0D4FA6C3F1574609347F81B36811243D8AC82A3004AE207A7107D5B356AC894BAE4743332E3DB4751F7546C13152A21BE64B689E9185F0D720BBC35D451308DED5F12E042F04358EC091A2B7CC28ACC83C08946DA410FCDAADBE8545081A67B96B91AD76C9C67AD76446BE6EA7F4C701027CF724809B3008DCD2B0C383DF5B712BB46EE43F2C0463394B460AA7FBAA8B8FAAF182ED541C7740F3AEF3C8C8ECDA6D8749BEB5B93E9F32354E19E15D92A30BB39CFF49055774173638452F56D31D8C31C13562361B83E3C80BEE3AD88619E9672F7D245A652064B02DF009E7DDBCCEA5CF7390F55172C5DEF4A98E5788C9EF704F127F28C3BEF69034B50B94983633B04AD9813820ECB07966D0EBEEB871BD767328DE89C15F76D6E3A2673F5386216974A2CCEA967DCE016BAA1AAAE7E0F23AB532AEABBA4AA8283A698C3E8B1200FC7B703281A401BB70928D11B5A5F27998AF6EA5B2D4ABB330AE5C0A960A58C7E60CA1B50D1D6A53E1A9CE3C33A876BA13B465F86024423D244097ADA457D48E892E0E2638E940287E94E1CDA651B964543559D2807F16E45462BF02E948DE81075B83B4756788107A2BFDCE9A3159C4CD785F59498B75FCC76108D5643A9F3A550F5E93A7A0B48DE33E441CE063668999BCBBFC77B9777643EE027CBFBC3FADB5C07F6BE2FDCE2FEB497308B65F026903A2975F15342B335F0D3DCE4B80744A9C8D8283D18A0555F5AD48B80CD4AA77C06572CCDBDFF1D9049D2D17E23F843E +ss = EF215F75EC5E2F67DE8ABF225E3513EAFFEBE589280EFC35AE0B822DA239F24F + +count = 80 +seed = 09FC004519BCF85B20D25D314A0DFC79E00CB6262A7DDDF9C52473641AFB8CFA0F5DD5F53558184CAAE9EC34B459E98E +pk = 6E48F12D7515976EB80F7260616553575A19698F1FE9507BD3B2528DD096EE0C51DE2743E5D24BB0DB6A313BD699C3B3299D02AFD9A563D808E100CE9036B70AD5768409A0858FD1834699F557129E647989EC0160BD870B128B5EED5B3CBBFB4387BA4798BAA71E585E765189CAC7C828C05F5212D890050A220F5A55868B53E3EE1707664CBE5C0E03BE22F6231AD63EB531A2AA9C7259670E2FDB99BB732272147B563864B9D9CD7E828BC688F3F1DAA57271A8427A7A91D38E65D32BC9C329D8A18101B2604B2DCBC5FC1E458C1B3AEA7CE5EF31A82B27B5A28A77A76FF797C4B437D762E7DEE768002E2D9686E2A44C799CF1432EE92F322FECC6860EFCA22A857A1A6A5A20CC1B25D4BAAF840EB6A37FDB12E228E91842C337AAA35872EA9BFF453E64C39194660AA52D0E27EF47C52C1CB518D449EFAD220394FB4CC4D2E19082A33C8B20804AA32EE1792307823B49CCA024FA751B42A01CE375E27DC6325DF25A22F9CE55EDFC6DC74BF169456A16EF5374A32F70EE07C1C18A61AFEC87501101F89FE2902488A2D5B272B22CD10F0C12FAE418E846252CAD3307B8363D2EC404B19C1456BD75AD33195AE357F9EE009D49F58ABB20F00E0C020567698FD5B61152A70C91ADA239BBDBEEC16FD70CD9F82B6AB0C68DA58EB268457CC05139EAB1FB00112980A286933A948E6B8018874F53369695E05EAD8986AB0298899283F6C71A8C4656A1AE131022F2A2F36EDE212D9A8020C4B5CF0B7EF02D7B188373DCE8D8131072F5BF33CCAC31AF34F13B +sk = C08BA2EF8C3A0A043AFAD931652D7A19E6E8CB670F840DE5F1FA03309B2CA9EC5FE6141A25F7AB9F875F79E0A82D6EA5CDE5A017AB637D5FDB7C42646A1D71DF174E708D6185784938F57441688A68016E48F12D7515976EB80F7260616553575A19698F1FE9507BD3B2528DD096EE0C51DE2743E5D24BB0DB6A313BD699C3B3299D02AFD9A563D808E100CE9036B70AD5768409A0858FD1834699F557129E647989EC0160BD870B128B5EED5B3CBBFB4387BA4798BAA71E585E765189CAC7C828C05F5212D890050A220F5A55868B53E3EE1707664CBE5C0E03BE22F6231AD63EB531A2AA9C7259670E2FDB99BB732272147B563864B9D9CD7E828BC688F3F1DAA57271A8427A7A91D38E65D32BC9C329D8A18101B2604B2DCBC5FC1E458C1B3AEA7CE5EF31A82B27B5A28A77A76FF797C4B437D762E7DEE768002E2D9686E2A44C799CF1432EE92F322FECC6860EFCA22A857A1A6A5A20CC1B25D4BAAF840EB6A37FDB12E228E91842C337AAA35872EA9BFF453E64C39194660AA52D0E27EF47C52C1CB518D449EFAD220394FB4CC4D2E19082A33C8B20804AA32EE1792307823B49CCA024FA751B42A01CE375E27DC6325DF25A22F9CE55EDFC6DC74BF169456A16EF5374A32F70EE07C1C18A61AFEC87501101F89FE2902488A2D5B272B22CD10F0C12FAE418E846252CAD3307B8363D2EC404B19C1456BD75AD33195AE357F9EE009D49F58ABB20F00E0C020567698FD5B61152A70C91ADA239BBDBEEC16FD70CD9F82B6AB0C68DA58EB268457CC05139EAB1FB00112980A286933A948E6B8018874F53369695E05EAD8986AB0298899283F6C71A8C4656A1AE131022F2A2F36EDE212D9A8020C4B5CF0B7EF02D7B188373DCE8D8131072F5BF33CCAC31AF34F13B +ct = B83A427119FBEF4EBA27B531807C1EA04A4373504AC6CB9967630BEF6C2D81716364380CB6191FAE6D7B165981AF82D50595C8FD1F7754A35EE027D4EFBBC539FE69377B40B9BE0CEA8912D675AAF90CCD686AADCE2566810387C3D79F40A1FBCBCE1EEA634C622D8C274A9227AA9FEED6A797AD183A7E85B96E407FBD06568A9F75DE8B22C03D10C3FFF093B320CF499A8130051903DCF6F154A6BE80840B4E20014CF4D4BC177DBF426E7AA078326ACABCE7BEFAC054C611401D66839416FEFE1581378A8716F3680B87CC0639048EEE79183F589978C9DF2360850CCB88816378B8C6B5924DC280C6D4D98137E35E5F8052EA512EC9691B085E0A77FAEAF531A7BAC49689F707EAD5E99AEFFA36F7139D55C46119DA395237A783365F34442C7901D0AF903E794FFAF0E1C504A2B093658B3AC404DED029273379162A648C64A48BDF5A438AEB2BA183D9E4691744D21DFE1E58628D8C52030FB327F7D674DD7FD2D027E723A6456224A1213AC09C6D4DB12365F0DC272BA870D905151021848D416F85FCFAE55742FAB57D09E70FC24000605D9DE62BC229B32F8EE9F869D31838DF9CBB9000296E562A4A11EC1A12CEE4CF14135CD913E87E221ADB16FB2A3DDF39FF20513219DE93A2EC4F9B28D3A953142726FD8E17A717E0B89D3D595920182FDD2C03AD7401E1766D0FCCC72D95B490C116693BFFDC0CD352BE3D47259ADCAE911736880FA90AEFB1E9BD257FE61E466C22A9FE227BC470A0679EA72B5AA02101BAB1B3D9795AAE4875811B72CE9A55C34D69381E2202153DE0EE0B5250CAEDDE90FFCBCEB209BAD4397D1CE33DD440 +ss = 4A14C1B95864A51D1211B0110C208BC620194747173C7AB5FA6FA9506A2B9540 + +count = 81 +seed = E3C41CCA6F04CFE7732FD54DE30CC5CAAC93E2F80E76AED7D24A962A3969C1B6A311459A3EC3E510E3E9B1E4291D4D7D +pk = 041704A36E4E207346FFB4A89B6E7B1FBD03AE2C3DC645B8C1F73CFC10F502AE18882E23954AF62F1F35142FCCA1D696475C88A5C31862ACA4456A64222E342411BB0444C2FC6FF92E4293DFB56CDADDB4195CD1C62911EB359C0534EA45951AE874CB7B31559F7695E373F7A9087896FB08661A7F39C152AF9EC00B8F301AF813907DFDF4F432668CD8E783F23120B791BD0559381BC9D9BDB0C1A71E6C9E6CF59FF7DF4ADA4DC30C3F20CBB2E3C2D6EAD6C8E91E845ED3AC953D130A5B1160413B27169EA6874A7F62F5D9CF365D628C959F8DCD42573E2A12661E14CC0FBB000A808520C2B89501D164E9583ED7524C5089849C541EAB673FA9748EF18A97F982C3921141E58E6977DCDB4F6DB5915EA40C911C33071C5352CE6D38320845477631199B2A8A2F675FAF2E107F1C7A6439C176393A02ACF530DF92708B2AB53A600D65117844DFD5D41486FA08C6F3FB644278186691CFDD4E0DB49A29B332E5230E9825CB09747E6F31DE5016CAC74CBAAC0121E52F35B0854A9C4C307DBD9449ACCF724E3DCC87B47F2D0BCEDFFB1325C4AB8BC90CB296E7346292B12A629043F9D59B87D90856A07B3817B1EAF928BB6D92B660FE5BDE103941F706FC31C6CA2A609886F4988D4161F3D6BB3BAF686CE44FF8117BA74A2279F251405FF9104591A9A2C0C9683A8B7665EA69A8C389413CF8686F7140C64C413C2AB761E19B3090AECDF14AFA78A461FB2E3D4E7E2A1AB49DBD043C63C0C3A0896AF485329B221251272A59DCD1B5E6921B7BF57629EF125F +sk = 0E3B30E102D707538C2671060F603BB0B8A014103F132D63B09ECE07E4A4C75B11EAFECA9E810796C34E8CFCE9D59342884456007B01DDD12EDCE6D10ED87E4CE709B0A4180D920F87F7286402996002041704A36E4E207346FFB4A89B6E7B1FBD03AE2C3DC645B8C1F73CFC10F502AE18882E23954AF62F1F35142FCCA1D696475C88A5C31862ACA4456A64222E342411BB0444C2FC6FF92E4293DFB56CDADDB4195CD1C62911EB359C0534EA45951AE874CB7B31559F7695E373F7A9087896FB08661A7F39C152AF9EC00B8F301AF813907DFDF4F432668CD8E783F23120B791BD0559381BC9D9BDB0C1A71E6C9E6CF59FF7DF4ADA4DC30C3F20CBB2E3C2D6EAD6C8E91E845ED3AC953D130A5B1160413B27169EA6874A7F62F5D9CF365D628C959F8DCD42573E2A12661E14CC0FBB000A808520C2B89501D164E9583ED7524C5089849C541EAB673FA9748EF18A97F982C3921141E58E6977DCDB4F6DB5915EA40C911C33071C5352CE6D38320845477631199B2A8A2F675FAF2E107F1C7A6439C176393A02ACF530DF92708B2AB53A600D65117844DFD5D41486FA08C6F3FB644278186691CFDD4E0DB49A29B332E5230E9825CB09747E6F31DE5016CAC74CBAAC0121E52F35B0854A9C4C307DBD9449ACCF724E3DCC87B47F2D0BCEDFFB1325C4AB8BC90CB296E7346292B12A629043F9D59B87D90856A07B3817B1EAF928BB6D92B660FE5BDE103941F706FC31C6CA2A609886F4988D4161F3D6BB3BAF686CE44FF8117BA74A2279F251405FF9104591A9A2C0C9683A8B7665EA69A8C389413CF8686F7140C64C413C2AB761E19B3090AECDF14AFA78A461FB2E3D4E7E2A1AB49DBD043C63C0C3A0896AF485329B221251272A59DCD1B5E6921B7BF57629EF125F +ct = 4B698A0CDCC0764DDCE2F61B2AF10D843C232D8CC68711722014DB98858400607BA1EF424447CBEDB6AAFB1ED39A1D0D1EBF1C8E6E5EE86564530F78B65B7873C404EAC48811BDEAC7A8CF9762782C1DB5BBE7FA8A99C235EF979EC6BC3A081BB05536277590A822DE6E9C43366ACB7EE3A15FB7ED30A6F3154D4A1165084D91E4253053E46410E9658D1E918D8634904D978B3DA11BED64964EB644F3F0F580EF07F6ACB443CC739DB60245B05DB0B631EE8E43416DC4FDC89A2C51561A4171AECFA47E269B2296F80289A63E06D88E927977227ED5FFA7AEAF6068B6F813A470CA59F08DBDF9C0EA99EA1B0F11EB10C8E3ED8454FDC2393C678E85D4AE0779EC1ED3DA653AB6169CB331ABC1B7F25676D83C0B2C865E45BF3202FF01F211B02E35180193585598A1554F34983B2E171598548972D4ACBCD1B9A48BBCBBA3424DC333384665B6B2EBA8D89218033685264DFCDF3F61AB167189BC855A880E615CBD79E6EE11D3EE7291FCB44F68E5A6AB0DE9E37B8CBD10E7CD59CDFD9A0A9E2AD4572125B6E30D8AAAE127E3F835078C75550C5315582F2EB13D5C0A631AE1D62889EAC3036EC30902AC626CE65A079870D5276B65F17C304A0B148F14A59DA3D8C9F8DE692199163BC943ACE3F046B01DD5766A146C20291DCAFD4155956A481B378A287C6CAFCED72EADED585AD7D0F5FEC0BA4EDF95A6D8FF0F0411218D2BE82FBE4613210D6EC93BBB6F00008787F605EC2A9DF03E6B124F2EB4B980514CCE0DF8F8B95CA1C09F7202D0622B31DE35C06CEBF64B0313A501103E409761707C0834EB51803F006E4ADC254C20B3643DF2D0 +ss = 8C46A9F4111F3A275FAFCE4FCF0BBCF828A0A9006D0A9C632F1B5B8E669D23C4 + +count = 82 +seed = 373FDDE922CFC416ED96B444E445BDD0962E8989F6C50ADF9912A89937C57217D3600B06C95440448E3F601AE69CA5BE +pk = E357B186939C36F8210DC79500913C46A9E810E369EF04C311B4CF5B5CF4F77FA4993177B5F0539A452FA61556D3965D71D5EF74E23DFD47A290FCC09439D1479E9E1A17DB29C1DD4DA63447E0C39CEE3BBB59E5FB40488376590790986BD80C80B8DD7265A5987828DF6CFB6EBECB92D653A0D0743B54B61E41490A443243F844E78D8675300110F7AB3C48940D89D8709C589DD1BD226765E9A12DC41760BFA56739087A37D39BF9F44C6F4CD993473F6DCDEF57892670E337340CFC9FD2B9C32F9A0877E7AEE38780D96C6F707FBD60B20144D0435450302FB39B7C630E9101681874E5B2B8E59B62B8EE3B2C85BC4A31F327C54D027586084756EF92722B21AEBA7ED22B861E1B40FD65FC0F36C844976A84DA5A30EBCF0558BF79843C7A6DB5EF6F710512E639ED27D7CBE7A7E814A17D025C58FD8DE232A8343BE5884248CEE5EFD7AEFBC067D39F997692976DC86AB17092D0AECB6ABCCDDA1BD2E57599AC17772E129863F35D8EDBB37E091351DA3F88584E7E3B2CCC0142FB1736667E1CAE68A703BD6829F441A81E3D97804ADBA77C6F6B9C1262B079FCB1637852AF897F8D2F52EEF0DF9FB26DA750FA610DD769016C5E3EAB042BC8B44EB64E69B187E07DEC64603A030ED13863EE4328457E05475C06E0CE974A1063F5C0E0E38941057F9D40ABA613417FA3EAC57F2613C21BEB47C6486A542F56196501AED4679420F8E1F4D110715A3BED5784528FBA6274E4B7CA43A9F751DA11F53C3962B6E96E4AD9768B623AC6036C38F884845A24B00F +sk = 2478F7D3DE6041E7E5CD11C5E2EF483D1AA6218EB126444091535F6AE532FA7311136E2681DF2EF881B51A092A9BADBE72C9772C169808521C47149578621E28952F0AEFE4CEA4E32A3BC47C86D24C01E357B186939C36F8210DC79500913C46A9E810E369EF04C311B4CF5B5CF4F77FA4993177B5F0539A452FA61556D3965D71D5EF74E23DFD47A290FCC09439D1479E9E1A17DB29C1DD4DA63447E0C39CEE3BBB59E5FB40488376590790986BD80C80B8DD7265A5987828DF6CFB6EBECB92D653A0D0743B54B61E41490A443243F844E78D8675300110F7AB3C48940D89D8709C589DD1BD226765E9A12DC41760BFA56739087A37D39BF9F44C6F4CD993473F6DCDEF57892670E337340CFC9FD2B9C32F9A0877E7AEE38780D96C6F707FBD60B20144D0435450302FB39B7C630E9101681874E5B2B8E59B62B8EE3B2C85BC4A31F327C54D027586084756EF92722B21AEBA7ED22B861E1B40FD65FC0F36C844976A84DA5A30EBCF0558BF79843C7A6DB5EF6F710512E639ED27D7CBE7A7E814A17D025C58FD8DE232A8343BE5884248CEE5EFD7AEFBC067D39F997692976DC86AB17092D0AECB6ABCCDDA1BD2E57599AC17772E129863F35D8EDBB37E091351DA3F88584E7E3B2CCC0142FB1736667E1CAE68A703BD6829F441A81E3D97804ADBA77C6F6B9C1262B079FCB1637852AF897F8D2F52EEF0DF9FB26DA750FA610DD769016C5E3EAB042BC8B44EB64E69B187E07DEC64603A030ED13863EE4328457E05475C06E0CE974A1063F5C0E0E38941057F9D40ABA613417FA3EAC57F2613C21BEB47C6486A542F56196501AED4679420F8E1F4D110715A3BED5784528FBA6274E4B7CA43A9F751DA11F53C3962B6E96E4AD9768B623AC6036C38F884845A24B00F +ct = E98C9651DEA501244945955E4E25C57AD278EF4A61B49DD7E60F084A8A573D6AB5D0002B46FB44F1E249546C04833710F883D87FB6AE1AFBEDD4DF071833997456D68B8404928694FC4C107A70D5234DF92A289E204579EC393F7E223952EE4C09D9A6E6D3A14B813629187CFCC36E9ED1CCF6A96FE08E6D33AEFC745495F6EBA92D33389BA69CFBABE57B42C45B6F24868C84D57BF549A4D3D9BD9B30BC3CE93D7975381054B299EAC6538A7487FD98B0D8815BBE91181CAE12502690050FB4E5DBA5664D229D6278DBA8FDDAE823604262B4BF3BD79BD3B3E959AE62F380F1F931A2CE3A6B335533EE030AB65940A4DDC515D6D76BB5EB57E3E46660256BC2ED07CEAFB854779BD3C7ACBA03BED8925A153B58E064CB227B45DEF5BF520C26F6ACAA0D3C1666025F257B4A54AA769C4688F9AC4E50D741C9CA88BA8E039ED1E1038DC8A93973ED2E5E6CFE6F2F4D2058E84120F535AF233FF0200597574B924ADD9E68CAD09D12B8764D4FC09253B952E0A4F87529523757C73A101D5CB1BA1E69E7B9EC244555097A8700B74E8232941AB254A697F5BC3E8676E878218C4BD3AF2A6DEAD4C962377AFF00291CD1C8DCB48C969FB8EBFAB6799539324EE4979FCC36453479826FB598823EE109CAC375BFAD10B00AAFD967D4A9DB29131BD651F3C3B3D5CF6509838682DE8AC6032125CCBA8A5102B95C8AD8922E42DB60343BC5E4A7AFFFDF71383A7C1DF6D769D159500C8EE6BBE0AA872903FE3C4B7E05B8B0A8FAAFA33A957ECB50DD576C8BE14352BA3CEC551C9125B002ABDACF77D37E18B7BC704F4FCBF7812D3DB385962A25819E5B +ss = 60F62850F54096EF4D8AB44D5050086D48889FEF1D2523B2BAFF585D2E4BDACC + +count = 83 +seed = 16BEF67F7AC3A755C59C816478B75FCC16CE5844DB537791ACCD1EBD49D2824B105FD2E970F728C8F0CF16E439A9AE2F +pk = A4F1F0D3BCB4691FD6DF0AA806F5DBBC4AF3A47AFBB54322DD3AF167990C0021CB5048EBE843FB7F2F0E2286FB118A51131A72DDF244F29027BDACC0AA35B5201E8BF62A6FB9975EA343774742712697F04ED316C7718D8D232318D2C026AAACD25357315B80B2C07108463CF087B8543920832FD1BB3E086C23DD931BF8DC3E644D7D886521E49141ABA61616C0AD9A020C3DB87470A26CE2693FD9E686C856DE27714CDE70AA995E9D1F6BB272D80A375ACCE6B51FDB10B205D500ED999B1F7BD9E9F5A79542FDDEC48C34CED28D85412F7E12C607FFEE47E7596C98D986A8D960ED9694A6A6143CC2F5C32FFCC5ABF00DD9632AF44FEDCD811C9A78914E075A1961B1AA46E3F24F5173BC56847DB2B3EF6E11123E482A4605613E90A553DE7F876AA6074FC3858B0556157882CDF89FCD44088C598B63AB0268FA41BC4886917086905BE1346536B1AF177DCB8D22A5FC935E0214AB750AC844F4A2D0446BC313F2837396230E5EC23A084303D71CEAE7808F10D9F3590E8838DBE5F092E425B8ADB9296D4FD078A5B07A7DCD477DC170B772EBC8CD21A730024756BB11BB5211B6E5796E520C99FA75AE17550903BCAF567242ED49BECF7EDDA5DF6074EF88B1A8616EBA5571CA1C561046EA69DFC49F5457E146A3EB23B328BCCA188541EB92CBE5B7B23D9554F29B56087236F08CD81C446E174773ECBB28FE1D82D95B62F045BF118CA14F8CBDCCCDB740FE7EB8D2BFB1BB154E6B479B0D6520E87B9DDFBB30600AD55978BC8B57EF5DFAA9BAEDF2BF6F +sk = 9D405D3EBDAF35FA8722DE431B669722ACAAEA2FD10B814310B17F78B66147D16CEB14F7662BE0C42779459F69A145C0E2CE9F0BD9A0CD1BF32ED5694CC9AE32F1EEF33ECE28D20086A1FD00DD3EB903A4F1F0D3BCB4691FD6DF0AA806F5DBBC4AF3A47AFBB54322DD3AF167990C0021CB5048EBE843FB7F2F0E2286FB118A51131A72DDF244F29027BDACC0AA35B5201E8BF62A6FB9975EA343774742712697F04ED316C7718D8D232318D2C026AAACD25357315B80B2C07108463CF087B8543920832FD1BB3E086C23DD931BF8DC3E644D7D886521E49141ABA61616C0AD9A020C3DB87470A26CE2693FD9E686C856DE27714CDE70AA995E9D1F6BB272D80A375ACCE6B51FDB10B205D500ED999B1F7BD9E9F5A79542FDDEC48C34CED28D85412F7E12C607FFEE47E7596C98D986A8D960ED9694A6A6143CC2F5C32FFCC5ABF00DD9632AF44FEDCD811C9A78914E075A1961B1AA46E3F24F5173BC56847DB2B3EF6E11123E482A4605613E90A553DE7F876AA6074FC3858B0556157882CDF89FCD44088C598B63AB0268FA41BC4886917086905BE1346536B1AF177DCB8D22A5FC935E0214AB750AC844F4A2D0446BC313F2837396230E5EC23A084303D71CEAE7808F10D9F3590E8838DBE5F092E425B8ADB9296D4FD078A5B07A7DCD477DC170B772EBC8CD21A730024756BB11BB5211B6E5796E520C99FA75AE17550903BCAF567242ED49BECF7EDDA5DF6074EF88B1A8616EBA5571CA1C561046EA69DFC49F5457E146A3EB23B328BCCA188541EB92CBE5B7B23D9554F29B56087236F08CD81C446E174773ECBB28FE1D82D95B62F045BF118CA14F8CBDCCCDB740FE7EB8D2BFB1BB154E6B479B0D6520E87B9DDFBB30600AD55978BC8B57EF5DFAA9BAEDF2BF6F +ct = 565FF76C749334B07E05D036DB9948B1223D840382D16C4A1D22DA6E482D78D368CD0BB837125917C4A8E284467EB0231AD84B3A69F955FC3AD37866AAB529B705D56C440FA81E072248456CB687F21F92BF8926F54CC4D7EE776F24C24328C74707890867394D29C9B84BC52DBDE1174DBD94985E116F1D191BD158CC2A0BFEC5AEA2872CB10C6D1D2AC64A3C9A9B83329EB5A9C82FFD452AD5531DA5B87C1B309D52FC39AEB9A07BE6F2307A198267487D24E092E0C4516DA0E44D0366C2F12CD2CBAF9F0C013C4BE6BA698D9E195F53407C6E4887FB8958D75AD71F1B069C58703681235DDD163B934F56EA74714A58AFE1C9B4C6B15513CB594088C238621279A9EA36089B0C4CAAB949B151CA79788A66F2BF0DF1EE8E0740382D385FD8317EEBA3C6D89948638A598DEC4BDE58B86461185EC13D232DE3DB999F0B03F395F5FB96ABC90EA5B706438A2DFD7D79F100A0D65BD2089FC902B1F79762AD19F65816DA545FE3CE3181A0F8A9D1C9DE4ADF495BD92BE9014F7209591F4D3A056CC207D916E38566249A98F05CF2918DFCAAC68BBA833889987BF54F3E72E2DA4A0C4350015D4CE1F420B25BABA8B295017D62B4FD30FAE5512A139AB505EF42191029F941D960B9D7110A810EFB5DB54B53C87FB52B9F08CF6D88B967B2B80F8F855A78DC3C1B20B0A8771CB6934BBDE64B9B18A248B9948ED7A793FB7AE940167460BA5F1D032BC68FB1066466DCF70F4B1C9779C02D9D633A32B550ED588E3C738EEB58DDE8891D661818AB7417F0DE760D2FF3BAFADF7D31747EB031A6A192486C9C5B2692BD9C7B723A7E0939BBC19EC3FD +ss = 4EEA80450240413B5947E8CC918E91C4F1662655FBBBB2EEDBA9D802B76835F9 + +count = 84 +seed = D0611F9AE5BE4DA5D7EADC9109944348E716CB3DAEE545721EEA8C892E7831CF2E54603146454CBFD92387739E9A78D8 +pk = 357FABF2CBE3D7E413570C13A56A570FB19C115E13C58973ECD430A99F26B9A9CE6F7268948ABBF5A8DA9FAEFDD984EBA46456081A969DBFA813273BF238EA6C264044F002861F960EE46181C9AED04C15237CF8429E7C1FEE759C304468D100078274CB29F792CC1AAE4D8946B30280893F7D2B4A88872F48A55CA2DF2AF9656A65065597CF4C4E83059A772A336FE2A2EECDF843BF352430FB17C6C811EE8B50A6A9512F4731E3E8BD164351E8C13DB927A8961B43F113BB7C493C150776E08824BD262906B1A1FDA7A7BEA8FF49E3EF04E1CE5C331356E89D03A8846357B6F3AABCA0DE8894EFAF4EF3FB6AB54F0027CF923A017A3525EC63EA51CAA180FFD6DCEF2CA184CCBE2BBE25E8A6C04E002E3D2DD1AF01BCF2516CBF4EB2AA12CAD283814F5B3235B4C007471656B488DDB24F86F76AF0F3717A8DDEAFD1B388770EA320F0541C6C0305AABB757C0CD787633A76F27C27CDF41E61A1A77F1DFABE9C25B21DFC17667A9B22C375B7C7B9672AA26962DC0ABB633461144D73247DC0D5B794045C0966754F0E552DE7B7F9B83BE74DB65851A8146A3815E407C0D917CAA48C8CA69EDEA9227E3C0863BA0D68D4C66DD7E092CA41BD7FB532C2DF7EACDF5E5FB45A493D7D50AA3756B7D0A08D8FCB38819463148EA214E3FCE9424D8F6327B6D87B8DE0F56B84E9D1189DBEBC3F69B6E2FEB6CE344F54F662BEDF8FD38ED72C31DAB4C9F5CFEC06B6E8E6AB20B1FADC09B8A5BB66DCBEE045C778DDA6CC3EEA62C42ED175879E10E65CC51ED4FC9DC361 +sk = 9A86490F0615F3EDF789CB0654066E9EE339CC59F968281F3B89213F83C692EDFAEB2EF44D2F608621E831187CE79B2D2F4A20F1568BBE76B0D3D5AF361117140D780101E59B3D63CCCCA74C0793CB03357FABF2CBE3D7E413570C13A56A570FB19C115E13C58973ECD430A99F26B9A9CE6F7268948ABBF5A8DA9FAEFDD984EBA46456081A969DBFA813273BF238EA6C264044F002861F960EE46181C9AED04C15237CF8429E7C1FEE759C304468D100078274CB29F792CC1AAE4D8946B30280893F7D2B4A88872F48A55CA2DF2AF9656A65065597CF4C4E83059A772A336FE2A2EECDF843BF352430FB17C6C811EE8B50A6A9512F4731E3E8BD164351E8C13DB927A8961B43F113BB7C493C150776E08824BD262906B1A1FDA7A7BEA8FF49E3EF04E1CE5C331356E89D03A8846357B6F3AABCA0DE8894EFAF4EF3FB6AB54F0027CF923A017A3525EC63EA51CAA180FFD6DCEF2CA184CCBE2BBE25E8A6C04E002E3D2DD1AF01BCF2516CBF4EB2AA12CAD283814F5B3235B4C007471656B488DDB24F86F76AF0F3717A8DDEAFD1B388770EA320F0541C6C0305AABB757C0CD787633A76F27C27CDF41E61A1A77F1DFABE9C25B21DFC17667A9B22C375B7C7B9672AA26962DC0ABB633461144D73247DC0D5B794045C0966754F0E552DE7B7F9B83BE74DB65851A8146A3815E407C0D917CAA48C8CA69EDEA9227E3C0863BA0D68D4C66DD7E092CA41BD7FB532C2DF7EACDF5E5FB45A493D7D50AA3756B7D0A08D8FCB38819463148EA214E3FCE9424D8F6327B6D87B8DE0F56B84E9D1189DBEBC3F69B6E2FEB6CE344F54F662BEDF8FD38ED72C31DAB4C9F5CFEC06B6E8E6AB20B1FADC09B8A5BB66DCBEE045C778DDA6CC3EEA62C42ED175879E10E65CC51ED4FC9DC361 +ct = 56B22744548EF91C2F0811FCF5BDC62983B37698E2ED28D7DDB0AA79BB42C17B9947DD636E45679350DA9D24F2A15DE3C738B9949D5397CD8A02FF0A5B66D65A2AAD718B04C455294962EBF38F956643679B4357A487CB01BE29228DF92C4E6391072A1C0DC7F5C5B14961F94099FE1DC80594126DB0796BEF36578E7ED1F9906F81DA2C82A6411EBE3EEE3E0A982E28CC36C364C0A8F68008814B563AA3F678F59BF660D537CCA396615027EE545F97B5620B1FF190DFC7B9AE8D6857C2BF31F774B0ACD47D6B888FE872FC53C98CD5C55BBB86D833B8149E6AD1674C066BA52E6318934247F719C5C480163140F5D35C453496272C1481BE03C6D02B7D439DBDE93D052F16A7DEEE3260B107C6191642E1270245AD8DDB3557602C4EF62AFC82BD219CEA91A49D517911A0721F17AD4D3C6EA086A92A2EA2BE3745EEAC7DC161A09E34262B0557103E8C37BCBE342C497D12EEBFCFAEFB6B0DA5F2C2BF3A6AB18A74093B955FB2BB7D08D9B8690910809E41882B9EAC64F570570E8CABE8416B00623A2F9E142403105D8218AEE8C00341A8F788E36EF7B2AC5B63EFD07596586A63B65639B4D996930D960A62320BBA380E9F4888D6C25E3FCEC4D1D08373E790761FA866AD991634AA2BDB3B010430F027F98A0AB6CD332CA1F51B0C52EB2EF64529B0BA219B4271C36F90F56949C3A28D5E5E68B4F597633B854E24EFBC76C3060F4A7C431C3CFDD1CBEAFB72E4FF624826E1BB1616349CE8DD55612F2E135E01382383AA3E4D2AFCB6E01D532BA285602C588915FB3C5132F0C0EFFFAA16DB4074B7536212AC8D9F50FBA334A3C337CD86 +ss = A6AA55F4F84ACE96FCCFD113B3B77E885748F05E84A0F8BB68B5B59AB3813116 + +count = 85 +seed = FBC38D7614D7718E931EDB850D2C6F0C5EEA9EE889B3E25BD69AC255D5B91E885D93E808E66BF9C88C655DC594DA5792 +pk = B07AB0A3019C122650F9943E8C119F20B439E27E835361555429F82F1EDE2260428A1B198DD686B0179DFFEC22CA9CE5C0425054F7D5C7C528D42420A1E31E32CA63B59F6C07FE4F2A439F745983F7B680BDAAC6F8D87D1B1F7AEDE97C6D7D4C60B2CCC554339A990B885C6DC7BC2E90944ECEDA3F74FD97CFAEC5E0118CC07884CF28DD0A0575487A8BA58E27B3CFEFB54AC34470AC154713896CF18F6153CF106D642C549986CDFB21C0244F8452722FC9BF157F876E0D4F3D3D149134609E8A9BFB3108FD3AFF286C288B1237667761631E66984A762634B66E33704EE7329CFA378BE7E0535CF7E8260F70A4EB841AB5AE252DD5E51C3E25E0A3DFB1778794B2076A1C7B33A5CF6001419440329A6FEDAD110E8CE3B20B06809B1A286B5B577793CDF09469A17441B17DCF0BF9D404BF425E327080BB94D1B39EB36BF7DAFD5BBDA1D19C12083E010D2DF159120902DA05C3CA9D6C0CFF7FBFD0E016AA3481A1E391BC2B5941283B5762818AD931A3200A86A1E13E4C5980D94AC647D43DF8D4B7BAD3DC777C2673218D959E2A3397D575BC5966B63063025F2E7F218ADAEE82DFEE66F1C66C717FBE5F7FD88B5797EE5D7427E46528A609D1D0A4BFCEBF7C0683F0790C748BA844EA7A50C2ADDA009B5DBCA46C5CD65DAE4DE0F9B4EFAAC3DB7A742668271900EF149164BE08D88B0F0C198B725CB58380AB32067D4C390156A1DADDD0DE051EB1CF58A752AE90DB0B7E6A3567FC3F88226D8F6E50DBA5D8F6C9700281DB88C35FBFE569CF1064F6974133 +sk = 6DFD9B575872560C7BDC2732C4A28DAC4DB04E535EB8E402C3DFFD145C09CE47A2985C1C4D203778597947D710DEC806E36B0CD949FE460EF141213BFC525E5BEE66291AE5E226AE015D9579E3DFC800B07AB0A3019C122650F9943E8C119F20B439E27E835361555429F82F1EDE2260428A1B198DD686B0179DFFEC22CA9CE5C0425054F7D5C7C528D42420A1E31E32CA63B59F6C07FE4F2A439F745983F7B680BDAAC6F8D87D1B1F7AEDE97C6D7D4C60B2CCC554339A990B885C6DC7BC2E90944ECEDA3F74FD97CFAEC5E0118CC07884CF28DD0A0575487A8BA58E27B3CFEFB54AC34470AC154713896CF18F6153CF106D642C549986CDFB21C0244F8452722FC9BF157F876E0D4F3D3D149134609E8A9BFB3108FD3AFF286C288B1237667761631E66984A762634B66E33704EE7329CFA378BE7E0535CF7E8260F70A4EB841AB5AE252DD5E51C3E25E0A3DFB1778794B2076A1C7B33A5CF6001419440329A6FEDAD110E8CE3B20B06809B1A286B5B577793CDF09469A17441B17DCF0BF9D404BF425E327080BB94D1B39EB36BF7DAFD5BBDA1D19C12083E010D2DF159120902DA05C3CA9D6C0CFF7FBFD0E016AA3481A1E391BC2B5941283B5762818AD931A3200A86A1E13E4C5980D94AC647D43DF8D4B7BAD3DC777C2673218D959E2A3397D575BC5966B63063025F2E7F218ADAEE82DFEE66F1C66C717FBE5F7FD88B5797EE5D7427E46528A609D1D0A4BFCEBF7C0683F0790C748BA844EA7A50C2ADDA009B5DBCA46C5CD65DAE4DE0F9B4EFAAC3DB7A742668271900EF149164BE08D88B0F0C198B725CB58380AB32067D4C390156A1DADDD0DE051EB1CF58A752AE90DB0B7E6A3567FC3F88226D8F6E50DBA5D8F6C9700281DB88C35FBFE569CF1064F6974133 +ct = 8014C8E6B21C62E83314FD35A543634F00B01B2E7C4E69E2235B8623C4F9864075E9ACE7E40A97BC7B7D7B3760DC94A20AAACFB41FB6E9302AEBDC8F4213002053880FE627E881B82F1AF3240CC5103D293B1DE611180CD5C8D2FB6B766BDCAE4A7BC6DB69394A89972D13CA5C4EFA7DE1E606C4727A6EE1CE823F61BD5A0FE34504CE27AD8F19BFA8036F672244BF419A91CCA57A9D7636CDEFB0B108BDB828EBD9F50CED08614C3303E560C442AF9736D0B9ABC40FFC32F7F07E6447B5C6D245B97CFF59BA44AD91334E4672920D4F1315D10F3E64A1442EF3977AACA4097325709E27EDFF23186F7FD453C5E2C00225B4DD7CFFDE68FE1182FE6B95FA20CAADE781B5A62DC7BBAE73DA71FAF0497A21EA091632AC686E42388F17A1B6AC18B6492679CC93C58EDC2D53D8A0B448146BB088C9DF562D20770D1AB7A5604177363D8310F46C32E1448B749D59B8C622EA66AEBD61DB79F7CBBBBC495E01F7FCBE62BEF36AF333F7400342227932D455C837121DEA84906D1FFECCDD8918AD57871D66360E7B11AC61FF63FEABEEE89A4EF7A7948B70D9E26F37DA6C3FE282AA7635BA521148B65931407DCDB286C6A49A67C95BEDE7419EBA3797E0FB7A99A11069AD2FC7492A740B6051B037F3DC0C7B13CB19685DF98ACD75DDFECFF0ADBD5BDE1CC6BDB24B44AC1D613C620BBC3792798AF6AAEC149C377CE1DE8F9042BE9180C2CF7C92BED88BB296C63CEC96F1FBCEA69855EE86DB16DCFF8BF231CD150BFDB97BE8D05A7986AA486F794DD3EAAC8BCE5BE5DA0AC156FDB73A3E782779F9DBB2E2C16E20043DEB3CC70A0F2F02A60A1E4F +ss = B51F055A645FAE20F634F62243B398358544C00F2E93DBF55FA69EA82C00B43A + +count = 86 +seed = 1722219CB5DB47374EB0AF0232C856A57F026F1CB09E5A5799F4C333DD422FF6A0A67C4DA502FAAE727FB2D45DAFCF35 +pk = 7629D4954E6C9A88D538C9244E4B1DA169E4970B68F99EFF53E1B9F264001CB2A611D4D4FF9E2DA1F34CB46716D2844F5C5FAF4754466C7B876DF53E6EBC4E1756114873EF7E1917E6D8CB7D69813B55D1F5E9890648099B6489146993529F215FDF16B33DD99C3662C373428FC0F92299DE54683DF24477309824925CE8F692CEBC315CD657BB44F7B1EDE85B478A3B4DBAE3947BD570349A0E29E16B91D609140A2CFE86E42F98DCB951782EF42DB127331E357FD4CC6EC05D5D6173D3FA18006A8023B0A6A351A9E9DD4ABA65279AEB6C52B290E34A4599F3A7DF14E9D12786F1EB7DF9DAEE0DCA38AB92CFD13491FA241812BB8039E7766AFB90D23D66775B3C86CEBA6181EE4253EC497A876BBEB2CEFFE048F3CFD51710EB3A30E3DE14E6250A505A611843EB31A49B2E4573B622CA372799195AA4553AA7BEFBA720156D4B68F7A877517C1C1FC608DE41540266DAD557475E17F5807F0FF8063AD977A22D4D7D123A2C7006142ED809C6D1AE3962174F9206A46350A5F5127FF540D3DF7F0D9916D5748E10BE5D0FA62CB40D9FA9E079A696DC77F653D5D54C055A91778D4578FBEC17DFCAF29A72B40679A0CF92AB0789417BC78ABAC22FC75D77613DD47B3AF8987F52247B4AFE9EEEEFA6C05637D8492FD509ECDEA08971671611A569D00A0610BAE4839201EE5EEBFD7B37F47DDF29A701D0BCF9CA30D3D30F8E6BFD8E3F3AF8BD0C7CBC1770BBA18E96415795D74A09A3B9C88437FBFB5A3C73CD3A0502104A912C3EFECB1C8D219BF0EC05D855 +sk = 6FCA9F4E384D8418075CC064C70730801BDB8249899D456A77130D5BEEB3662CCE7683F8A03D3CF04E46970FF7D6A12494AE12558346DFC8FD9370BF944A01022AD673C62EDD8B7D17F5459C9D1DBD017629D4954E6C9A88D538C9244E4B1DA169E4970B68F99EFF53E1B9F264001CB2A611D4D4FF9E2DA1F34CB46716D2844F5C5FAF4754466C7B876DF53E6EBC4E1756114873EF7E1917E6D8CB7D69813B55D1F5E9890648099B6489146993529F215FDF16B33DD99C3662C373428FC0F92299DE54683DF24477309824925CE8F692CEBC315CD657BB44F7B1EDE85B478A3B4DBAE3947BD570349A0E29E16B91D609140A2CFE86E42F98DCB951782EF42DB127331E357FD4CC6EC05D5D6173D3FA18006A8023B0A6A351A9E9DD4ABA65279AEB6C52B290E34A4599F3A7DF14E9D12786F1EB7DF9DAEE0DCA38AB92CFD13491FA241812BB8039E7766AFB90D23D66775B3C86CEBA6181EE4253EC497A876BBEB2CEFFE048F3CFD51710EB3A30E3DE14E6250A505A611843EB31A49B2E4573B622CA372799195AA4553AA7BEFBA720156D4B68F7A877517C1C1FC608DE41540266DAD557475E17F5807F0FF8063AD977A22D4D7D123A2C7006142ED809C6D1AE3962174F9206A46350A5F5127FF540D3DF7F0D9916D5748E10BE5D0FA62CB40D9FA9E079A696DC77F653D5D54C055A91778D4578FBEC17DFCAF29A72B40679A0CF92AB0789417BC78ABAC22FC75D77613DD47B3AF8987F52247B4AFE9EEEEFA6C05637D8492FD509ECDEA08971671611A569D00A0610BAE4839201EE5EEBFD7B37F47DDF29A701D0BCF9CA30D3D30F8E6BFD8E3F3AF8BD0C7CBC1770BBA18E96415795D74A09A3B9C88437FBFB5A3C73CD3A0502104A912C3EFECB1C8D219BF0EC05D855 +ct = 96C256C10108ADF521BD7180C226BC3401A732A49BF1835331BB4E041E6C61A676140B5FE3AB0BB6EEE7C4669A337EAF882FF1481BF7A136F5FD0615DD4AFB690D8C5D7ADFA2EA7B16D4235417F064075DFECF2D20A80A41F8F7FAAF8022D961108F57BA2C520D4ACD1C1B94F238CDB6A235C1A2DF5E06E88AF74420CF0D2CAC87FFFED914BC29777679D753F9C4ABD19F79C7030DAF00CBACABF4403973E11DA4B14AD1451555FBD211C7D9CBEE39255D03ABA6E867D062D5497E66519F13C1A3F2D7D6D154A79474D1000C10ED9557ABE4A8809C554EEF24B18941C9862E5DA543DD93B64F345386C36861AC6D852D44737563FB59B5A9E551EBC8753C33FD0D80A0D8883492FDB027B75927A64E21A5BA41716AD126CF283951B5AFC13B0D71B91A666D45CDBC1FA664ADE5D0710AAD016666B62D699AD757B94C403C673CC33E882F294DA467401C47CBA806364ED4C9D133A11520C81700142B545EA35CC4B0A3E66E473C44D093600E7A334CE22E309DC8A5073F1AB09A52A9CDC8BD03B056B4ED7E621C026B833F8902A9C3925A9049F0D8E8FF22FBB447746429DA3B992A3E99226457DB4406AB8848986AC1276E4D025D8FDEE89615D6CAFA09F00F707CE989587966D548FFC387EDBEC2B8B35F726F671E8748AB2FD3A3956D67CEE0F6D2D601814756418F4E459E96999FC2334A9C4A00174B08E7970DE8394583D413629F730642BC8F356E90611CB48571076F87DAA46FA9C0273C4DDF1A7F9F89AD2FC25CE8451D427311B23798996F9D219E3647E53D5A740CB20F0F6BB0A63071658ADDF3EF567EE1CD411D89D4C77EBBC9F3 +ss = B8FAEF117C9BAD91B8BD4D1A37FB64485D9C9A010468E9E4EA5311DB7C8857C6 + +count = 87 +seed = AC139B78FD16CA0F26D6D7F9E15345C888D857B1910CF38D883339B37EAD2DCAC30F7CF10176F23FF34B4488EB79437C +pk = 9B8CB5CB24B5D49CB5545CC058B9A460D1D01A838C834FAB126433A39EA4638264DC835FF19727C6F0BF0B45359CAE18BCCE46F96F9F2D1AF3A8316EA6F494B69C1BF4B6A4FC4BE3C7D43469BA7EBF665FDD70B0F71002B5D3F3A009C755807A7088FDF9BE242750540BE94A5D66A0FD063F3378BEBDF3CC6B0737D5DE3D042E9766CE77B8E50A15468FD37B7BCC9CDC8C306DF81FB4DBD7EFFCAC03A00F33367B96DB5BA30A70DFF464C5662AEE43A35C87241045904D8924C2B626382E9AA4BAE378D7D908282D8638EBE82D6292410EF1B12DFDEA47D1DF6EBD552D1D831AB334F5DCF7088256AF89D4BF33C58D0D87CFDF1F0925EC91EA7B89045A2C54BB6EC722DAC095D58CA5B8F9110176048934520022E10CE3F84551DC8B2D164A89ECFB0C93B60C81F9023140D92D686F0D7D686FF632CF78A6314624A59B1D0520CA05C4DA610577987CE8BD6FDC78F5DE5EF8982606760869351BD0A141F946CACDEBFF0C0256087D42C61E42456ADE4418DD8955A0F7550A3AA5521F02C51931C31065FA3BD7DBC97DB1FC3AE90CEDFBE9C3A5C5972A00AC1805CC84640510DB54C4BEF01809495A677E10528ADB931A67A8B87EC3997C0F1C32F5D91A0DB2EA2DCA3CCBD2F0E1882F95AD46B6F90B37EDF4FC282451F1224193D499002EC45531B45BAE0B772CFC15D7D27CEBCF0DCC654C2DA5FD5E46005E50E74CB18550D68596A5AAD953BCB745564F4523DD89D35967D0F871A400A569B6A9400F67B4C19F1413AEDDF55362004AF1DB53491C38361A1762 +sk = E58F71BF175C0550A67E00E0F7B3B7FC36BC2707BF0C93044A492626DE36301A7F7054814869CF7625E45647BC1547AFF288DBB90699B2AD84893F3B755D9722814394AA8D7C351EC828975853DB53009B8CB5CB24B5D49CB5545CC058B9A460D1D01A838C834FAB126433A39EA4638264DC835FF19727C6F0BF0B45359CAE18BCCE46F96F9F2D1AF3A8316EA6F494B69C1BF4B6A4FC4BE3C7D43469BA7EBF665FDD70B0F71002B5D3F3A009C755807A7088FDF9BE242750540BE94A5D66A0FD063F3378BEBDF3CC6B0737D5DE3D042E9766CE77B8E50A15468FD37B7BCC9CDC8C306DF81FB4DBD7EFFCAC03A00F33367B96DB5BA30A70DFF464C5662AEE43A35C87241045904D8924C2B626382E9AA4BAE378D7D908282D8638EBE82D6292410EF1B12DFDEA47D1DF6EBD552D1D831AB334F5DCF7088256AF89D4BF33C58D0D87CFDF1F0925EC91EA7B89045A2C54BB6EC722DAC095D58CA5B8F9110176048934520022E10CE3F84551DC8B2D164A89ECFB0C93B60C81F9023140D92D686F0D7D686FF632CF78A6314624A59B1D0520CA05C4DA610577987CE8BD6FDC78F5DE5EF8982606760869351BD0A141F946CACDEBFF0C0256087D42C61E42456ADE4418DD8955A0F7550A3AA5521F02C51931C31065FA3BD7DBC97DB1FC3AE90CEDFBE9C3A5C5972A00AC1805CC84640510DB54C4BEF01809495A677E10528ADB931A67A8B87EC3997C0F1C32F5D91A0DB2EA2DCA3CCBD2F0E1882F95AD46B6F90B37EDF4FC282451F1224193D499002EC45531B45BAE0B772CFC15D7D27CEBCF0DCC654C2DA5FD5E46005E50E74CB18550D68596A5AAD953BCB745564F4523DD89D35967D0F871A400A569B6A9400F67B4C19F1413AEDDF55362004AF1DB53491C38361A1762 +ct = 51F8D0392B0FA79A4E6C4EDAE18B314D674C75CAF4760F69050F173435AFA6DF90FB0E7838F856FE410AE6525B5BB60044A38F8C75FA2B492EA3708DDE9692C5DC7FC611EA03D924AB7F17F204818AC959B2287D24386938F52D6F64754A139393D4A647B99AE47EB1C5E7CE0B845717805D8FF23FA0E0CE99D5EA9A68CB6CF2C7783B4F48A41376A8062EF236B792E25ECEEAA6403D7059F1B430B291CCBE41F69EF55DC6ABB325633E37F564E6105E4876ED0BCE2555B7AEEA4B6638B03B123D8C095E6E975DACCB1862EB5D930216EEB4B403B8227467A07E6F758D4547F7A0DE3971C0995DA579019CB0DCC10D4993EF4FE5C323B8220BB6969C212E6FABE72ABF76AD494D0324C535B75F260E4BCF16E53B5A59EDF5FB4117B8689F7401715A423D66CC8890D6BF7F433DE1E43E862B7CC4BD5D99D3F0A1E3E07694376AF7F6DB0AE29D1D917CAC7B74727867BFA60E5B18239AB4ACF9335540F0F916F3738B299DE39AEB573D58C4F573856108697A2CE32961602EBF638C13E7416046BD526A6710AFE5BEA5F1E3FCF10C31E14B11D6569661490FF1C48A41A2C1D428932E6A6B77F6F25165FDFBAC52D589B5E8CF323AF7062EEC2B445F96D52E6749D95C80C9A0DE0706CFC28D5A9167086931056AAF1544FF55B65D58AB35417A52782F6ED29547F83D87D6CBA07B242AB0D686DD61F218467F5507B38231ECFAAC2F49343E48FC3F999FAB5AB94F8DB246C3A8EC0E183504E717F8B157C8604BB1B9A994C7D05A3E930D06912AD02F422A7DFCC34990A494DCED1573C611B3F8B6B836A6C2C47FA0FF9BEA298BDE3A04CA0B129BF3 +ss = EAFACA5348B53B62BC5565C113BE92CD302B694CF1DC54FC30205B4D5DD815ED + +count = 88 +seed = CC7152849C98D5FED2813275D32069E44824ECB14EAEF425CE017448CD9A401C91C06D0F7EED6D22B7BBE8BA6C429EC3 +pk = 5B9752DC03E94B0E0DCAAD5B96CF86A7B29A5BEADAB46904AA02EBFFF4DA14F4DDE9116E95E3ECD38BE2626A397FD2EB9B40E2390D83EB0A338034D11D084B1C771CDFBC2D7D290638D549359CAD4A8CF6F71FFBEAE540578E725DBCBA5A822B76CCA381E91BFC44D7D5F837CE79489B9162B5D3427F17FF370014D75021FC7BF71B694A8752F1F15D4079AD079009CC1D5F0395EA522D232160225FF382A50D022F208C859AF110C40CE8DF1FEE25F372A49C304B9E936FC9FDC53A1D4F85DC962ABF3CAD68DD5F1C25ABC568B093AC64724660ECD14A2D9A91D19145BD2561B7F249933057E1693932B9D7345BD740E22B21E6B4D6C1175C385330F6C47E7BB79A3A2F2A5A079403E15099CF7C7F33D552634AB136E910F00E5218C88A52657FB5913F45893259C1F62B1210A3AE17D42494B1009683729E49005E64B8F927075E9AC7DF8254337413025F2E83DA25039F50C73B8B79CF757659F805F579ED5A9552DF284B0D6EB853BE60750DC0E1554BDAD04ED0292709AB8C18C0BF8953072AFE03BCD9384A4C395230128FD73E0BE5B6C26C2B3D9E64AF5F8433BB76FCE6B7F13DE6DB093CF5ACE0851BDA462D208D2E019010474B7431585D788F54C321D5A60D8CCF787A699EA2DAE9C093B93526286E1A4375CC330063361779D6A02800327713701C4E12833ECF1F588302B4A5C9E17058CAE0A59D2196024A6CDC79735853299A2E48405C990D3CCB56BDC4688C53A2124E023522B86A16EB51AD417832C9AEE6A7F78A588739482B88CE93C56B27 +sk = E3FC575ED51513E62ABA655D24CD9C8F1C6C848AAFFA946C49A53AC3EA59E474D82C2F1BF2E6AEBDE5660FA73356982E12999D8FDAFBB3CB186341D0386DEAD06ABF589AA1E7C22EB20E04C5ADC4D6035B9752DC03E94B0E0DCAAD5B96CF86A7B29A5BEADAB46904AA02EBFFF4DA14F4DDE9116E95E3ECD38BE2626A397FD2EB9B40E2390D83EB0A338034D11D084B1C771CDFBC2D7D290638D549359CAD4A8CF6F71FFBEAE540578E725DBCBA5A822B76CCA381E91BFC44D7D5F837CE79489B9162B5D3427F17FF370014D75021FC7BF71B694A8752F1F15D4079AD079009CC1D5F0395EA522D232160225FF382A50D022F208C859AF110C40CE8DF1FEE25F372A49C304B9E936FC9FDC53A1D4F85DC962ABF3CAD68DD5F1C25ABC568B093AC64724660ECD14A2D9A91D19145BD2561B7F249933057E1693932B9D7345BD740E22B21E6B4D6C1175C385330F6C47E7BB79A3A2F2A5A079403E15099CF7C7F33D552634AB136E910F00E5218C88A52657FB5913F45893259C1F62B1210A3AE17D42494B1009683729E49005E64B8F927075E9AC7DF8254337413025F2E83DA25039F50C73B8B79CF757659F805F579ED5A9552DF284B0D6EB853BE60750DC0E1554BDAD04ED0292709AB8C18C0BF8953072AFE03BCD9384A4C395230128FD73E0BE5B6C26C2B3D9E64AF5F8433BB76FCE6B7F13DE6DB093CF5ACE0851BDA462D208D2E019010474B7431585D788F54C321D5A60D8CCF787A699EA2DAE9C093B93526286E1A4375CC330063361779D6A02800327713701C4E12833ECF1F588302B4A5C9E17058CAE0A59D2196024A6CDC79735853299A2E48405C990D3CCB56BDC4688C53A2124E023522B86A16EB51AD417832C9AEE6A7F78A588739482B88CE93C56B27 +ct = 173D35170149E831AC26A31CA920B76892E8901236F82A06E2248753C1CCB5D1C2956B74B79C4411DCB5118FC4B5DABA7007447596A1B31D0754F4AD4CC7F58DD97E7537AF6437E05DE0078AF1512447A60D68DB87A688AA6CF267C870370201BE360C22D76A3B77EBBBF83F499D7EF48B107FED34E5E2159EF61C9DB893DAC4526854D21E5EE6DEEA125D0824B46730B4AD6ABD09344C9FE1D2CAFCA253A1138EE900DB10B1EA3B511AE984884373C87FE25BDA88A56657B3BE3E5CE3360D6FB4BF9ABF59605AA46B70B1FA91EE53EE427012E97D6EA4207B490B199E4D8DB0323F475E07F13102518C63FC08A814047D6C0FF7161CB9496DE6BC3534D0F04CFE793F5E951DFC01706811D24E1A73502727234D61E20B87D66FBA7D04D732C4E90D8A7E1E3FE4521637EAF75F5CE851A3C764858FEB1B8FCC27C55B262083E61DD5FD33D8BC88FD964E1AD5525A2C3A915BB65ABD7B146DDE2628FD248352351A4B9C67BFBC4070D4CC52C2CA8E967BE5F5DE3CD4928D6419EA08D22A5D57C2D70F47F4B3DA160BCDF062EAF76EA76F5EF1DF30C3504E099DC199DAC0FC13B001BF7C9A488A9275AA42401EFB6325060F8CF939D4FB080323D6D258A95BDD22E1FA1FA9939868C6233370F3E6B371B428F87B150A269F8BC99F7FCD62DBCF964E209ABD13E49BE6C9BBE2F86A30EE8E7D05760CFA488851BE9A991F1C49C1A41AE98DEEB701F1893A3080417D9932C17E7384375DA80AEBEB2F07DFE756078618F78579B52962636157B1BB1B09F5E61106624069027B44E245AA8F0C66AEE7ECEF9F2729C9E2FE281F92A866B391C667AC0E58 +ss = 623C452049FBC352C8332F8BC3060C96A6BBC4EC0691EE5B4792236E0941D288 + +count = 89 +seed = 96D9A06F88FF2C2036FA8E914B89C765E4A510B468DEE40F914F78858C811857EFE9FD0E17C0048E7389E8D996B7E2B0 +pk = A50A1AA5A6C4E8A8940D4E0ABF7B16AB4AB0BCDC0476A6114601A28A62F66F1C38D940BC006215B2EF330E6055DC82B7EBDC95E46E22D842357D2FAAC11EB12567A1ABC32085D30640037FF1FE55B45EB9B62A69E0105F2ADB8DB76E2C44522FFD5796A7791E965EBFCF1A9D6A025E0AA466A03969BEBC4A0D824607DFE4B35192819658E482060B047EC9C79F337CE377FCFC84AF9C22C123D29512EC8ADA6E93B877FF34EFED992DACEBE70BC6963D81766664419C4572A6A4205AEE9DA4846E726C95E0CBFA3AA753BA9698A7921587D0452189EBECD916CFB4F7BB1C901CBF8936F0CC7C98E5623BA1E957B5AB974553B9ED43C5ACB9BC2F1294BB60D7589EED6C802BEF5A3F1C284D909BF48BEC78AE3E3A22663BB6EE2B2A05E94ADA30663D853B28561F8A66A3B5D364FA7C933D79E990375027B99F55D595894768779B8C7A030F7D031EF5214A11524BB94E7EFCFFF142AC499E0538744C68C34E425EED5D743D434416570630121F7C9442B1B7B4BF3D1385429791DC3A12D4E5752FA04CD015A277CE4833FB982BF82E1DC5960D7A0C19F84531F9A94A51BC95F64879CFF12897A36ACCA9A1070692D6CCBBFB60FD2BDF97ACF9D32014FCFA93E2B51ADBE6C707B155E7121C47D4D66B959F9176B42C5B6688A8ED0754C8D3356A2415196B5088B50D72E95F6E711BA62E2525067D35C3805D36DF38F979FB23284F23F2AACBC414F989E347A3BBC74DB43B9FDEE69734B8579958605E1BD4B43624232C6DEF2DC557AA0882B5DDE7CFC9E8DE8A52 +sk = 470B4943F0FE7FD0D8EC5185ABA0D1DB09D112934E4FB4787E2BBC6B88466E7B8B2809FD40008BE70A6B184981101724BC3D5EC5E1956B510B82FD5AD0668A5A4C4CF8794833434B07153F4FCE619D01A50A1AA5A6C4E8A8940D4E0ABF7B16AB4AB0BCDC0476A6114601A28A62F66F1C38D940BC006215B2EF330E6055DC82B7EBDC95E46E22D842357D2FAAC11EB12567A1ABC32085D30640037FF1FE55B45EB9B62A69E0105F2ADB8DB76E2C44522FFD5796A7791E965EBFCF1A9D6A025E0AA466A03969BEBC4A0D824607DFE4B35192819658E482060B047EC9C79F337CE377FCFC84AF9C22C123D29512EC8ADA6E93B877FF34EFED992DACEBE70BC6963D81766664419C4572A6A4205AEE9DA4846E726C95E0CBFA3AA753BA9698A7921587D0452189EBECD916CFB4F7BB1C901CBF8936F0CC7C98E5623BA1E957B5AB974553B9ED43C5ACB9BC2F1294BB60D7589EED6C802BEF5A3F1C284D909BF48BEC78AE3E3A22663BB6EE2B2A05E94ADA30663D853B28561F8A66A3B5D364FA7C933D79E990375027B99F55D595894768779B8C7A030F7D031EF5214A11524BB94E7EFCFFF142AC499E0538744C68C34E425EED5D743D434416570630121F7C9442B1B7B4BF3D1385429791DC3A12D4E5752FA04CD015A277CE4833FB982BF82E1DC5960D7A0C19F84531F9A94A51BC95F64879CFF12897A36ACCA9A1070692D6CCBBFB60FD2BDF97ACF9D32014FCFA93E2B51ADBE6C707B155E7121C47D4D66B959F9176B42C5B6688A8ED0754C8D3356A2415196B5088B50D72E95F6E711BA62E2525067D35C3805D36DF38F979FB23284F23F2AACBC414F989E347A3BBC74DB43B9FDEE69734B8579958605E1BD4B43624232C6DEF2DC557AA0882B5DDE7CFC9E8DE8A52 +ct = 80F2A678D9586068514C42DEEF6B7DAEA43ECF28CC5E9C7D4E17337D6106DCC8D8B34156F7AED23DC236577DCF2EC147C65FA35BA6431C2ECEE5E1656CA1E1B141B610305C7EA10F2CF4E0DCEDF6CC4A8851D9E0012E387147792AC26B00C98B6CA0CA51D51FB1B0CB55A643099F7B3CB4CD4C9E8017E1E624EDEFE5225322A709B592FF2E51981E108F1F93E342F09E1254128756F928668987BA203D647D59E3C9F81A946D10283845BFA5B6000C4072ECADF355313881DDC7E801B3205BECC8FCE83F4C18ADF6993EEE5C40472AD07A353C3A9EBD733899288328AA3AF314E43AFF4E9B7B6B667025434DEE131C37ACECDF09BDC456D65384021DE5F2024BD0960CEAE3D2A5E3E7AD9A82480F3D30529C8C654E263397E220EDCA10FBE0F3EFFF74ED4BBE546EA9F338273B8E012370048BA06A5976E2C19ABE29DE3A564EDEBB92E089DE0ADAF4A6D91FA6E24202B69ABE4EBA264BAA9A04AF40917E0FEC119F2E15FAA2B7390E2030A53CCB4958766E286572E2D156566955B244B0A9408761AB7581C8259665F06E361D6BB6CDEB6AA41B7F3D9F4C9FFAE9DC423007BF5E33360AEC933CF113F45E64B58CBC74111EC55D9FBEC66BE36D1FD0CF120B9EEA442F3DE2BCD516A1F347E0A5566D6266A6F6152E487DC1D3857FF203D518CD6290F5B47620ACDDDB6184C12C714B122CCC75277BB49180DA116CFCB2EF059865B6737B93D8F41D61ABB8C74D57DF7F5722FA68567979C8F539E75F4C9A6FB4E779F5D4C9A0EC16D207DB95613715FF68F0F035F0C27596A032347A2F748C577EBE07C1E6B70EED73289EE99204984656171B8F +ss = 6914DE332BF69D644EF33F1838FEFB16A62069B48C8DEE9308169EF59C7D7E7C + +count = 90 +seed = D26CE360D399BF7B89DC364AA7AC06BB513EAB8F527383E93E30727EDC3F22C262AA0EC70257B39EDFF0630DCDC1B79A +pk = BDC498DAF0B6F7AE3016688ECA094049DF080075463F4B515D0DE9C7C501650D5B6CE955F44CBF134F2E81E8BE69E7E25CE6469F2F95F48860C7CB411B2E646EE84E60075CBCD25297A9713B6D53CD28B703B7D088831BC89C75BA72F15BE84F21059A64DDCA9904E68663F650330B9A0588E851BBC8DB587682C50C3C98405C8DF28533F0681B0640547DE65FF491EEFAD6BA8F81E5F12A5887261CB61819A6EB1E31E387C53F29AB9897995B4CFED2FB644B5D29CE0CADF7C8C2023DAF4EE814312BD2125C0D9BA6FFD0ED1030B0841909B23D970D92D67FA87B68A81B5ED5B77EA65720AEEBD0467C84671CCDD3F04C7181C6F41CADF6007E956F658AF06D2DF2C1CD79C4FD5885390B9FEF1B8954BAC0EA55B195CA47DD5461E027E2F8DB33543B275E3A38482E2A252D24DE36532BEBBD0A907F022F65DAE7F395B9CA17F16CF97E804D6B5596DE583A4DB170359A2A6600186F8773EA46E5533B6C3A0C9C4C0E4EE00A34A2A2C31406481565F0044AF94217F7E3000F9F02F040A8A3B1A2EEFC1E9B7BB7689521F285FF46109537D582874AD1B9D0213B31F9D145340FF96F5080BFF56382A0D513D7B7AE1E47C6B76336BA46C4616C9EAAE375ABEA59709B72CC076A7E5B13E423F582FF7A25F294722B724CD001E16DB5EB94571447773C18A0E506166F8BAB2AE1B6C68270B762DF8F20AF23263ACF8AB6BFFE5557DCA6D0B36B56B7CDB2106680050461BCCE418C836FC9144834A7AD49E16ED674115298411CB1615211F09E9E3F66509FA25EA744 +sk = 6DF4385DB978D27B27D2AA5E452E4152B36F097503D9581AC3390105C5727E7DC95FA08ED106CE84660E8A4C90BD2B22634E40769AA0090A101C5DDDAD45EDC5EBE6C48C21012C2B18C5AA931733DB01BDC498DAF0B6F7AE3016688ECA094049DF080075463F4B515D0DE9C7C501650D5B6CE955F44CBF134F2E81E8BE69E7E25CE6469F2F95F48860C7CB411B2E646EE84E60075CBCD25297A9713B6D53CD28B703B7D088831BC89C75BA72F15BE84F21059A64DDCA9904E68663F650330B9A0588E851BBC8DB587682C50C3C98405C8DF28533F0681B0640547DE65FF491EEFAD6BA8F81E5F12A5887261CB61819A6EB1E31E387C53F29AB9897995B4CFED2FB644B5D29CE0CADF7C8C2023DAF4EE814312BD2125C0D9BA6FFD0ED1030B0841909B23D970D92D67FA87B68A81B5ED5B77EA65720AEEBD0467C84671CCDD3F04C7181C6F41CADF6007E956F658AF06D2DF2C1CD79C4FD5885390B9FEF1B8954BAC0EA55B195CA47DD5461E027E2F8DB33543B275E3A38482E2A252D24DE36532BEBBD0A907F022F65DAE7F395B9CA17F16CF97E804D6B5596DE583A4DB170359A2A6600186F8773EA46E5533B6C3A0C9C4C0E4EE00A34A2A2C31406481565F0044AF94217F7E3000F9F02F040A8A3B1A2EEFC1E9B7BB7689521F285FF46109537D582874AD1B9D0213B31F9D145340FF96F5080BFF56382A0D513D7B7AE1E47C6B76336BA46C4616C9EAAE375ABEA59709B72CC076A7E5B13E423F582FF7A25F294722B724CD001E16DB5EB94571447773C18A0E506166F8BAB2AE1B6C68270B762DF8F20AF23263ACF8AB6BFFE5557DCA6D0B36B56B7CDB2106680050461BCCE418C836FC9144834A7AD49E16ED674115298411CB1615211F09E9E3F66509FA25EA744 +ct = D5C20AB2508B96EE86A836A75764520EEC8069BAC4085CFF0C116E3A2506253B475601AE6F6472A34050BFB03FCF96A63C1573EFDC7A80D30BA0BBA0DA58BEFE4E1168564423882D8D08625C20FEA09FC689388B8A1B6BA58FA6BEC23247EC98E032BF6DBBEA0B9F932B40A5FE5F80B5F887C2D0DB8CAEBD4FE3086AA3B4657C91C078706A3163FE8D21CE2E225936B59424D4C6FFA96CD75B68FB9E90D24F73F14103975A4491F6AC6E5C174F9433EDBCFA1EFBD59EADAFCE529F6751F5E408B693CCB70195F387DC8533D8892CA4DFB97E0BE662BFF131A12ADB704801DE00B7B7AB2DF8DCFF099379B67738C08D64A0253E133B69F3FBECD0D22B05C2255B9F6301500BF4A06300763537B547998FCA69F5EE1DD5364EC326E2A7439AF2853812BCEA62F8F1B74C3DDF69E94E2910788C286551F6F3ECEFE2170FC04D92B5372EAB17DFB859589BB8DDF864CFEA3786FFBB9AF813559AB14CADB2FC745483BFFE77D359DD94D203F6344D8733E94A0D3770496CE866103CA6F2228E8D82D9FEA90979435E5C95C2B9F71843A3A60C3AF3CBDA6EF759D90C0860D06423D2F46F1DFC6358187CD9213F4C9B7E22F597EAAC0CB4023A04D2EC6743613A55BDF01DC8E241A447BE808E756809AE76038843E1E7B54930E68C7B1E0B030C0ECA22B8D526FE7D6E21DFF8283310D4FCAD256D67FDBA91135B57F1010DE43DF2CF803412C00A2CBDE298011445FFAD2A7D49278B048BCC1C7E6D306B486E743AE2D34C7F5EEC5CF42D93504BF224EA92DD4E42ABCD5A5263DDCB145E2E8F885FA4B8EB4516C0ACF8055366393DBE5F4E5A0E49F6BE0B +ss = F0072B8ABE7D3C6B1686702E58B9C9F15D91B3765954B237D851F441E976A94E + +count = 91 +seed = C5856298C3CB6AC9787A0F30938537AB2635B96F6D19CC9522063360E7A5C88E644929D2879180E3E5BCAD2422B7CFC3 +pk = 607AA92125BAB18B13C592C954ED788DF1FB03F561C714E376E62F4A4ADB5D1D619222F965B1CEE2FC37F2AF1BEBFF35FFE88008AFC5129AC52855D786B64F1C9C7CC076D0A9151AEAF6A35B4817867C0C2B33CA4B4274CDAE1D1CF37C50520ACBE26BFF7986AEFCC8A14C193EA0473AEBC95B29CA3926A1D862ABBA6EBB52030FFEF7F8BEC751ECD4D14F417151821F822B7DC92C99C7BBB7159468306FC551C419CA8A0A072C8ADC6624E230704AC2005F9C378908A1B64912A3397B7683873D70B3FA7F3011BA79639FE0D4BC18E0917CC999DFFCE56C8408B03632D6C221AE5F07291E48F1F018C7E06AF7BF949F0962F478BD7B716685A3698D06BACDF834E8F9AB3F23707AC8CF6F99B225853366F140F9DD5E93082600BCCCCF46B2EF7C764D081E12FE7D822B902F54DED9C5FE76345C4E2E3C0FDE968F9CDC5E7A48486DD83B431A34E24FC360BFB3416C38F1393584D51BA7ACD85BBEF257D290A40B156C089C6A48E2F7589DADBDC11225DBB01CE1D1CCC06250BDE3E8C39212626A0E40943E1A08F4886FFCD546F7F32E2AF86AFC56CA71B4F4AC22E0031B5FF5D9DBF0122E609E7E267AB3C04E79D6898334ACE0F91AC6CC0D4778D116AB7BA200EB4DC2078564803AD09669EB237249D5A87A5F7E5A1CF15974D15D0BAE3D5DB06767EDCABA0BAAA52E2202B7142DDE5F11D9FC969FCC10915EB159FD1FE22172E0D59D9DDA1C453A1909F78C3C38654FD38542AD422C9D863F2DB470D3DAB2606971B25ED7487F1DAB68FCAF52D7E6BC30503C +sk = DBACBA825728444921B227CDBA54446B3F6881B47BE9CD02832F78B023B1BEE0E15274A8E2BC08FE818B117BA28C5DFAE74D54FCDF6F20052F79BE333EDC8DDED341361D7317C5D77217C8122A4AB402607AA92125BAB18B13C592C954ED788DF1FB03F561C714E376E62F4A4ADB5D1D619222F965B1CEE2FC37F2AF1BEBFF35FFE88008AFC5129AC52855D786B64F1C9C7CC076D0A9151AEAF6A35B4817867C0C2B33CA4B4274CDAE1D1CF37C50520ACBE26BFF7986AEFCC8A14C193EA0473AEBC95B29CA3926A1D862ABBA6EBB52030FFEF7F8BEC751ECD4D14F417151821F822B7DC92C99C7BBB7159468306FC551C419CA8A0A072C8ADC6624E230704AC2005F9C378908A1B64912A3397B7683873D70B3FA7F3011BA79639FE0D4BC18E0917CC999DFFCE56C8408B03632D6C221AE5F07291E48F1F018C7E06AF7BF949F0962F478BD7B716685A3698D06BACDF834E8F9AB3F23707AC8CF6F99B225853366F140F9DD5E93082600BCCCCF46B2EF7C764D081E12FE7D822B902F54DED9C5FE76345C4E2E3C0FDE968F9CDC5E7A48486DD83B431A34E24FC360BFB3416C38F1393584D51BA7ACD85BBEF257D290A40B156C089C6A48E2F7589DADBDC11225DBB01CE1D1CCC06250BDE3E8C39212626A0E40943E1A08F4886FFCD546F7F32E2AF86AFC56CA71B4F4AC22E0031B5FF5D9DBF0122E609E7E267AB3C04E79D6898334ACE0F91AC6CC0D4778D116AB7BA200EB4DC2078564803AD09669EB237249D5A87A5F7E5A1CF15974D15D0BAE3D5DB06767EDCABA0BAAA52E2202B7142DDE5F11D9FC969FCC10915EB159FD1FE22172E0D59D9DDA1C453A1909F78C3C38654FD38542AD422C9D863F2DB470D3DAB2606971B25ED7487F1DAB68FCAF52D7E6BC30503C +ct = 02F957288B448D9CBE7FB4DEDABDEEF72E1CE4A68727723C06496C74A151D02DEC3EE07990C2E0B23E0E7326AD6C008CF4428F0B456E6492734D20A868D09F8A4039FE88B4534CCC19E05E5CD85AF9FB0D80A1AF05A52F0A8BAA9FE947159046E8310C4C1B98B6D98957D0A7C733CD3F97413C77D20100B5ABC306337AE061C691D10B3EB5DB0D39C3F954D7C5461B48E2765E2F0C9B3C15D3F95E4516F49CB2BFF237AFFEB3F2F09C02C91CC3D7B50BE2E98B2AF2C00EFCCA0FDB0F65FF4FA3E5BD3A3E82709720E7D08185ED5ADA93405E016C0779686CA6B6F60BEA313A5F78F451635AFC657D5FB4C16D249F82B56702E691D0A990BF904C31680B35D74F69033CF376F74A3FA3FDA4DF34FB6A63E94FB727BC01266AA025FF028A279037CE07B877D7BA00F26CFFC8378444DBB083FA481A7E231BF504A7221E3F6E71DEC37E1735090EE745B245845520F6639DB2BB8004FFB955CBCD0B3C2D4F100DE27DA0A8E85169B48ACD0D72E3294A9B8A4CC7F1BF400F196B632E64B2FCBB1DABD838536D500E3A8AD40E71030EBD46148F481B6898FC74321E7925F06A5700E76C62B30B381372B87ECD81035F6C36141D1F68F3117C047FE7626F32593164085F0C751AF353DEF425A8C5BA7EE828E289B53A887702E44A8D64B4306DF63B4906093B27DF461F16F08E5A76857161E89E9D7D55C04A6D3E6E984281F666B810DE2EF95D4E4D93CB51181F2D0BD606F12D49770B056417FA8B9A1F4672CC7C198F9F36B791CE71F8460D8FCE913B87FFF283476A5FD0A4870A7F2789FDF6DC25FF1F7159574F2D564CED41CED09DF544D70DEC11 +ss = A70CA9CADC09966C85907688FA6AECC1C0AE83FF905770A34FC6E2B3F8287AB3 + +count = 92 +seed = A28EAD0A08E7228AEFF602B16A1E752278B8ED1E91DAC67994F5ADC372E1D82F95CC390CD97AB9212275E0566C833FD8 +pk = CB7D596F44ACACA1BFC1AC93421A67874CCD1E863F2169B138EE62AB51873AD5C8A256795AE16111304799B409CAB0EDC00970A1AEBC6543E604E26B23839D8311FE4013406A5560DD535AAAEAB05825FABF62A953249BDD4FAC3696A10AE0B85AD81F8D3CC4E3047007BBFB1B4E2FFAC1D88B229A209324B811FC4EB340EEAD0B9C2650182495133207DA274C5B3B5316EF0E9BEC32030F49BCE0C08C545900FC0EE5AC684A35AB25B786D36F43C5098C16617C6EA701D96A1AB453287C9C9E979BC3225A75F90342092927F7FCB39D422B9C5444E5BB9B07DB3756245B5C9B082BA9B2746AC5B4E6D01778E3D7797AD780C051CFBF26F321683B706C11D7877DBC59CBB12FF2F3F1FC2896C8D82B5FA3031AE588605D886152E86C3F0FB0A59F1019401C1993A01CC1969E07B830EAD84D44E59FF1BDD5873A8511F59FA044F7294E329986B376F1FB85E9C201937D71702188A2F8A8881EFBCF8494D1BDDB1DCD26760BA5F1915013E764E48F1B15664E00B0CBBC7710F8495910FE6A220B660301131E4359E365CB84EF71A9390EF9268796895585FF5516926A655EBDDBCE4DC71B786180DA46604DBF7230B9564AC49E9C507D4363B77B668504AEA4234EF52A1FD412506B6E63A2539F14A801719ACC0736391796C5050BCF23957717131D35A3E47533283A165917B5071DE957B644750A8ED9C26EAE4A0C3394315B1FFB102294E305EC6103BE1BC6636FE1CD57CBC04F6AB80DD3059E8C6D366B6768A92811E79FF182513FC51330A5217AF11CAF19 +sk = 690EB71FD7052B906EAEC09937A8ED374E0B02AFA27C2F14399932BE5839FAD281C38C2CB5CFAFAC81B96A810AB749B61806B6D54C9F8CF4BF1BE0192423288F6A9E55D6AA936CAA943911DE027B9803CB7D596F44ACACA1BFC1AC93421A67874CCD1E863F2169B138EE62AB51873AD5C8A256795AE16111304799B409CAB0EDC00970A1AEBC6543E604E26B23839D8311FE4013406A5560DD535AAAEAB05825FABF62A953249BDD4FAC3696A10AE0B85AD81F8D3CC4E3047007BBFB1B4E2FFAC1D88B229A209324B811FC4EB340EEAD0B9C2650182495133207DA274C5B3B5316EF0E9BEC32030F49BCE0C08C545900FC0EE5AC684A35AB25B786D36F43C5098C16617C6EA701D96A1AB453287C9C9E979BC3225A75F90342092927F7FCB39D422B9C5444E5BB9B07DB3756245B5C9B082BA9B2746AC5B4E6D01778E3D7797AD780C051CFBF26F321683B706C11D7877DBC59CBB12FF2F3F1FC2896C8D82B5FA3031AE588605D886152E86C3F0FB0A59F1019401C1993A01CC1969E07B830EAD84D44E59FF1BDD5873A8511F59FA044F7294E329986B376F1FB85E9C201937D71702188A2F8A8881EFBCF8494D1BDDB1DCD26760BA5F1915013E764E48F1B15664E00B0CBBC7710F8495910FE6A220B660301131E4359E365CB84EF71A9390EF9268796895585FF5516926A655EBDDBCE4DC71B786180DA46604DBF7230B9564AC49E9C507D4363B77B668504AEA4234EF52A1FD412506B6E63A2539F14A801719ACC0736391796C5050BCF23957717131D35A3E47533283A165917B5071DE957B644750A8ED9C26EAE4A0C3394315B1FFB102294E305EC6103BE1BC6636FE1CD57CBC04F6AB80DD3059E8C6D366B6768A92811E79FF182513FC51330A5217AF11CAF19 +ct = 3CE525CA1195F98A8C21312FA7CE586758320A58B508D60EBB14DAA5649CEB3FB212D1A4EAD67ED3E8DFDCA2427A9316358B1D619E9C78E2903F4FC3D58873793710F7AA57EE6A2D713DD002443266408AD0CE0F4B9CCBB4C3516CD9DB3FD669B0C295005E169625C00F48BB1FEF51DC5DB9265D14C1120919CAEA27D6E89E817091D9EC155461D7ADB51AB89FB0E20310E9896AC4D4D0458E35CFDD8514D3DEE9C14DD7A80817AC4AD9F3CD29D93141847935AFB440CAB9EF754A693519B322C912DA9F70A05E45FAA8DB10CDBADA04C9A1265A1EE1943A33D8C977A7C34DB075DD1AA11A08C24E48ACCA899B4E19C62676E11C5538BE572502155B7BB7704195206192F32BD83BE8C71EA5FBDDDB7927AAD2EAB2CC541C403BF13B05AD7E07D6545177E2E6387A6B63FD24102F273F2A6D208BF6148BEDE6F17FE9F048489D39B9641408643EB9112CAA3CDF46B50EDAE0588CF5C71818048272766F922237B62C1358D7EF26ADCA5F44BD15C43F228E94F9786BDF2B6AFCBE339422C30D87D4CCA3E348E9C2167742282A147BB1DF00858398AB3096B3F52A2D4CA0AE5D33E8ADEDAA38C2ED00CCC1AFC17903DDB1EB664E4EDC19032A1FC02FF072FE285065541C5133A33DCFE013B7B3E4671555D22B2376044E6A56E82E519E22FB5E1B4D316DCA6A76870EBC3DB90095706B472CD17C67506489E861BBFACD0724EE4B71ABC91367D64FA4821F93AC8AE6A86E816A75459BB2DAE2E07C26422D1B6799968576765E28C1A269BDB57BD6FA52469C02A645F10DCD5FA285C03FDB119685459419989E7E485B1FAF57CA1483C885AE507BC0 +ss = FF6EBBCDD38D9A61610D7E3E450FC770AA2CE350F7DE4F6EC9838FA77FBD6B90 + +count = 93 +seed = 92877D706DAF88EF3412EB143DB8CD91BC047A9A43B7ACDAA42523560DEE4C172697BE4332042FCAB91135839BF74AB2 +pk = 4844E31EBCFEBE37F7373AA3B43800EECF64139FD37837DC008A9294CEEDCAA0DB3D5685E0FAA0FBC00F831ADCDE17361246E9B43B024BF5248EC3642CA9877C023795463C3A18150F78B9DEDA588450A61A72B6DA4A0EBF0BD8B51DB56FCC37C5D146C563319B60AB06359EA30AF2E5EEB6458FCEA150197B948181E34E7A45BCB560EAC289A4E83793F9529CD7EFAB360C48B6C10AABC01D586DA4256FB46B68D85673A013076A133E5D7EB381C5EA342053834B4FD0CE3514B65A7B8D930D04AFA7885FC3B31AB19D7B9B5D7443E96A307CC27CD68272F66AFC3D9C75B9137CF037101F7206FABA897FB64F924A75EBD392B83D2EDE47D558A39FEB68553C486404308B4C5E23ECC597DB7C9720663CB1FAC5EBD07D0A110C27908357670D6B80A5B873E57FC0DACED4478A168EF1AFD60DD48F31337523DDD7BAAE0A86C0DD85F3E07E31523F61774CA6C6228BB0E2604194E94CF9C27FFE8EDB82346A73E188B7C0E9EDCBD7DAF899172D071C07381587FAC49E8F5131BC94DD5121BE438344B65433A3CC2491D3E16759F3F17DB2688CFD6499AFB6C0C314B942617BEBEA9E2A524E902D1DEE1330D51056AF1B9ED656F400A6C0756FD5DFF56187261636AEFB5A8DE703A38D7DBD810385EE6F37E0ADC4BE2AD7F47278848D406BE2888ABEE8B1FF10D4F30DB42EFF29DAB08AA51FA4146A9F654A4D8D28C59E96343EA595927C115C4329064E80984071F8856D9610886522245C0F4B2C64C89389E8F5179D2C3BD66F08F46ED77A0DB5200A7EAD3F1F +sk = 32E0EA9089FA928482C0770DA545AF1BB871A03CE38604138B0D08EA2A10CA2BC06C5BEF7B6508409DAF847A64C8D30D0974FD3BA7476DC76C46B458A036D8844F53696845942EAA424C6F6CCC89B7014844E31EBCFEBE37F7373AA3B43800EECF64139FD37837DC008A9294CEEDCAA0DB3D5685E0FAA0FBC00F831ADCDE17361246E9B43B024BF5248EC3642CA9877C023795463C3A18150F78B9DEDA588450A61A72B6DA4A0EBF0BD8B51DB56FCC37C5D146C563319B60AB06359EA30AF2E5EEB6458FCEA150197B948181E34E7A45BCB560EAC289A4E83793F9529CD7EFAB360C48B6C10AABC01D586DA4256FB46B68D85673A013076A133E5D7EB381C5EA342053834B4FD0CE3514B65A7B8D930D04AFA7885FC3B31AB19D7B9B5D7443E96A307CC27CD68272F66AFC3D9C75B9137CF037101F7206FABA897FB64F924A75EBD392B83D2EDE47D558A39FEB68553C486404308B4C5E23ECC597DB7C9720663CB1FAC5EBD07D0A110C27908357670D6B80A5B873E57FC0DACED4478A168EF1AFD60DD48F31337523DDD7BAAE0A86C0DD85F3E07E31523F61774CA6C6228BB0E2604194E94CF9C27FFE8EDB82346A73E188B7C0E9EDCBD7DAF899172D071C07381587FAC49E8F5131BC94DD5121BE438344B65433A3CC2491D3E16759F3F17DB2688CFD6499AFB6C0C314B942617BEBEA9E2A524E902D1DEE1330D51056AF1B9ED656F400A6C0756FD5DFF56187261636AEFB5A8DE703A38D7DBD810385EE6F37E0ADC4BE2AD7F47278848D406BE2888ABEE8B1FF10D4F30DB42EFF29DAB08AA51FA4146A9F654A4D8D28C59E96343EA595927C115C4329064E80984071F8856D9610886522245C0F4B2C64C89389E8F5179D2C3BD66F08F46ED77A0DB5200A7EAD3F1F +ct = 51BD77ABD9D3DB71DE8E52323DF7252D4CEEC5DF926ACB40EA2092FAB125DF945685AC14BA5BD62994012E8EEA14A0C739DBC93E98D65D0B13A24CDA0D77474CEE19D281F532DA28F33808B001EC1076FE253CF8F009E6379217A471075EA1E44BA477724DAE6A4D2A60FB03D63B74ECF011FF827FFD2901B8DF86A6C45BCB28A0738C3BFAA8099D85B9CE4F8FBEC94F75C4C9D9969A75366787866C1A1970DBE379510203E72FDDC6F35C4BCC3AE4474964AEB0CCB4B870F79F6C25AB54064A413892BB7D32B8B162D97B1CE64E0EDCC1E0AAF06E4174E0C32242C8369D2DAFF7559E5795AD804E9EB8D83260073DE595039331B0DE0FA43B02BB9D45D3DF648622D9F645271C7F110E0754038C51D718491A230D77D8147208490CC655AFEDC9F6862A4A80F3B2134411EC3FC51210A09C605D330FDA76CC54C6DA9BA251E8BC13D4277063685F2A2BAC732AB1A890EB8A37AA29877356DCFD98297D8B208510C04C617BA0E57635996546508D06C5420560DAF0CFD06D5D137509FC0C127B5216B3388BD3E18893E660F33987BD7F692B1BB2D9ED78201511561D551BF39E368589D1810981686E33AC72953F9926B3D6F1950CE751F1DB2070E62CC3B441768651FD1C169D38612D5FE0AC267A7B7352BA42496DDD1B6FAA2DF33047C44E45769B81C83374CA139F727D64AE9D5A1F1D2F0136EC01E63D6CC73C340B83B8D08E3F05F2AF8FD7A5C755FDAE3455650AC0D5B35098B16B3516521BBCB9934ACB60267E430E34EB10D205877E09E3C1953ED13ADE9B6C7612E06BF5A161D2A26AC2678A9E3F1DDEC8E83B07A711127203175136 +ss = F5526D8ABC4C7F0DC7170F16D117E21B3028BA78B29B0C6B271092133B69C121 + +count = 94 +seed = BB4C0082CA4044B1FF60B036C9B0E0495D58667156786C530BC69D949A13BFAFF53798E456423D7A0E162A60039367D7 +pk = A3DDEAD7A0F983276C623A288A723B23499DDE4AD5087941C16394289A54E9B97D57BB411349300BD82740307298C002E7BE81987F4C6760F65B0A6AC71F11E13FB8904A735C14704219002F8A77DD0B648468023F522D90C5657F945D5DD64B1B21A02A9878EBB998BEFED4AFFD92E3B66FE8640331377B550AF4E6AB0B70719A68B6B3C0A69273062AED5BF6075F0C1FC6EAFC6041ACF70E77AEDEB518591B85024FD2AA38C19C23C5B8B9750F49D8E2B3BC466C2BA53CB75EB9601A08CB0BF19EB9916A6B8C127DFE04BAC02C614A632ABBF59A70071F5EF8EFA730D00024ED57A80122A879855B8BB4CDF6987ADE01C97651F1469309C486744B403BFEA087535184E155ED16B84A91F97E01C7B3333589F8312300BC7802266ABACFBDCE98C480598808AAED326E38CD4E5E5584ACFE7E901974CA782EFC28060594984D5FE7777481A223A872C633ADBBB53453981CE2B906A8D42199FC7AB5F018D5017F601A7FA9D13503B970F9A36589C4E2342F462EE81116530E8CF5DDE6B0AE404630E338FAD07CABC52993A796057984405075F4D657C39EE14013E7D37F24B572F16655BC693065E0B94862D94704509EDEA805ACCDC722C411F4EC9BABB8E696EC66C781DC4A9784D18560A557B18207C0D0452734FD6409B38BE52F4DDF1405B3A6B4696FDC89EC06F3332F0B806D824EDBAE51BEA386DC04BB6FD01FA46E3E79990D7F147D695A1656344FEF19C65E97296515AC2679C2820E8232F75048E453AE1A551E2E5800463899C0F6A4E459008C32 +sk = 6FB2EC719F2A0DEA152BF3F64B9D148F8AB8BA88F64E61F5DB53E12D59F525574F797C007E4061F95C7D56CFC7EE5C49E849DDE3FEA8F25E7876DF2A18515C349C03C3C45314774D82F5211B45FC6100A3DDEAD7A0F983276C623A288A723B23499DDE4AD5087941C16394289A54E9B97D57BB411349300BD82740307298C002E7BE81987F4C6760F65B0A6AC71F11E13FB8904A735C14704219002F8A77DD0B648468023F522D90C5657F945D5DD64B1B21A02A9878EBB998BEFED4AFFD92E3B66FE8640331377B550AF4E6AB0B70719A68B6B3C0A69273062AED5BF6075F0C1FC6EAFC6041ACF70E77AEDEB518591B85024FD2AA38C19C23C5B8B9750F49D8E2B3BC466C2BA53CB75EB9601A08CB0BF19EB9916A6B8C127DFE04BAC02C614A632ABBF59A70071F5EF8EFA730D00024ED57A80122A879855B8BB4CDF6987ADE01C97651F1469309C486744B403BFEA087535184E155ED16B84A91F97E01C7B3333589F8312300BC7802266ABACFBDCE98C480598808AAED326E38CD4E5E5584ACFE7E901974CA782EFC28060594984D5FE7777481A223A872C633ADBBB53453981CE2B906A8D42199FC7AB5F018D5017F601A7FA9D13503B970F9A36589C4E2342F462EE81116530E8CF5DDE6B0AE404630E338FAD07CABC52993A796057984405075F4D657C39EE14013E7D37F24B572F16655BC693065E0B94862D94704509EDEA805ACCDC722C411F4EC9BABB8E696EC66C781DC4A9784D18560A557B18207C0D0452734FD6409B38BE52F4DDF1405B3A6B4696FDC89EC06F3332F0B806D824EDBAE51BEA386DC04BB6FD01FA46E3E79990D7F147D695A1656344FEF19C65E97296515AC2679C2820E8232F75048E453AE1A551E2E5800463899C0F6A4E459008C32 +ct = 9F9FF21B5DC5F2367CCF107A40C5C06B0F3CC5CBE272BB107AD8DDA2FB8F410960C06380850F0E3B797825A72690D3108B77F281375A521C9AC2D900945789552544A4CE3FD221BBD7DA719670094A6C948918808BCEFB7483F9E3B14C126228A0E93C94C4A2CE1DF802CEA112F58FEF1552B578FA5EA7596DCD9D1874D8F8BFEA56BA1E093557B99CAB7AD52880D8DA5CEFC1CA44F2353B8B8EB061414BCE2886E315A99FB33063DBBE8200B4ECA68007146BE77B1C6D0C530D6B1648B7EBB263FFA729F9924C6E53DD84FD7702C7F64ED8EA6E6E212938F992A19C3221C4BE9E1B69FB0E1E71BCEAFD97D26911F95D8BC1422E570847B9F0A1A8968A8903B1689A3B1EFED1510BE6B4D5541A04E71734395B7855022D1B5F16113204788C0626789FA62673E8F01057A3E4B6A154E4EA8C768207109C8D1E3F05D7DCBDF0551B39BBFC71627412F9CDF0F8CAF9F17F92F553A378CFEE99CD7C672CB34C25FC9DC76B640AA8FAFA242F745517161A6C58703DBB21DE7A0C5BFC81976AA03B0FEF21A80FE3780278F00B88D6437FDE5013C8A1B68178BEA30EB0B8AAE374A91194ED388F367620D7FC873608CC0E52213AB27934BD7EFD308BA8846BB14D428131780D861FD293FA0836B7C915E72651F03B2008BE23383E9E3D8C505B5E2EC9ABEDB3634B100669E0790DE983760FC12DF64D20DA636321409DEB396A40FECAF2CE0A338C56F67E6B0BB51DF3284AC0249286D241CCA548BEA13FE924FC81F298B3856F83872EE8D0D078772DAEC795DA6D4F6F2175B90C66FD46B147BAD8FFE74B1E2CCC547E1C605BECE0D4C77FAE6D1297CF +ss = D7F0A7517BD8A4A25AECCAF23FEDE668DB53DB84A6CC09BC6FBB57F88C466A72 + +count = 95 +seed = 121D90E70AF6204445D0DEB28AC0C108262719E9FD3476ACA74BBFDE89FAF04D8D5F89A624E8A75DB80431F0D10AD28F +pk = 50FC5B70312F2FB129B1C13B76AC9791AA9631AE5EEDF9C98E38048ECB6168C67329ED29C2E340B87EB66D788B1ED1ED1E6F472510D712C7ED05852FB91AC3F47D3CE481F8840681E547021FB340DD4C54EB4ECE55920042433CD0E2414C47DE72C46FCFF8C7E000C45FBD515AEE02371F9467F6619761D2D5DDF32109EEA0CF5E8DF1112804FDB29A8369C316FC7C5934D005AC9CBB328FBF538C13110B71F5AB8B09789AFCEF40D81539BACC5062CB9AA3B2C262E21649ADF72351512C0F2E66098465322B7D82DBC89DEC68263939D72B09CB3366FF66111593630930F9049DE1DE0AD52CEF907EEE36B8DEA0F8DDBB9D9A7E642416A6970DBF62E8FB19B7D50EF8D61645A5374BCC796D6BB4D9710A762797BCA2404DD7304A3E396AAC9F6F281B5F136B68205E802A34DE7BC6F8AD637FCABE8E10550301F03C538D795627E4A73ADB77B244D038F71B38B21AE90F5F6877538A32005E3E894E51B0998A64E4C4A870C892100AF3CABC5898949B13B1C256572BDC35B7623F8204EF950BCAD9DFEFFCF0CF9FCEB38149DBB1C9772E7669279038DBACCE5EF5B642E6F2307D84E62E35805FCFEF2EB0A2C45E69306E63F73A9DCBEDDCCCFE95C2909611EA2535B98D39844D632B95A90DEC9EDBBF9A27886A1A4C8116C6A4D7C90E96B085DABCDB169950E0E5A275135F562E92B67C981F3ED0B3E7DA0E3B283D99EDFCB9A9B9AB9590BA3B253BDB4F8D80BAE986C4814641E6E6D5B08C1EC5DBA1D67F6753C8D74C8512D7344090937DE2E6114417AF9D36 +sk = 527FB88C8BD9A4D6031DAD15E63878ABD2B559E7E08D61F69E8E78FCA964EE6AE32D432B4F9F751BDE0496C580A181FFED762AA35454A02D3F1F47EE0394C89C239FAA654A488E65167123A0737F080050FC5B70312F2FB129B1C13B76AC9791AA9631AE5EEDF9C98E38048ECB6168C67329ED29C2E340B87EB66D788B1ED1ED1E6F472510D712C7ED05852FB91AC3F47D3CE481F8840681E547021FB340DD4C54EB4ECE55920042433CD0E2414C47DE72C46FCFF8C7E000C45FBD515AEE02371F9467F6619761D2D5DDF32109EEA0CF5E8DF1112804FDB29A8369C316FC7C5934D005AC9CBB328FBF538C13110B71F5AB8B09789AFCEF40D81539BACC5062CB9AA3B2C262E21649ADF72351512C0F2E66098465322B7D82DBC89DEC68263939D72B09CB3366FF66111593630930F9049DE1DE0AD52CEF907EEE36B8DEA0F8DDBB9D9A7E642416A6970DBF62E8FB19B7D50EF8D61645A5374BCC796D6BB4D9710A762797BCA2404DD7304A3E396AAC9F6F281B5F136B68205E802A34DE7BC6F8AD637FCABE8E10550301F03C538D795627E4A73ADB77B244D038F71B38B21AE90F5F6877538A32005E3E894E51B0998A64E4C4A870C892100AF3CABC5898949B13B1C256572BDC35B7623F8204EF950BCAD9DFEFFCF0CF9FCEB38149DBB1C9772E7669279038DBACCE5EF5B642E6F2307D84E62E35805FCFEF2EB0A2C45E69306E63F73A9DCBEDDCCCFE95C2909611EA2535B98D39844D632B95A90DEC9EDBBF9A27886A1A4C8116C6A4D7C90E96B085DABCDB169950E0E5A275135F562E92B67C981F3ED0B3E7DA0E3B283D99EDFCB9A9B9AB9590BA3B253BDB4F8D80BAE986C4814641E6E6D5B08C1EC5DBA1D67F6753C8D74C8512D7344090937DE2E6114417AF9D36 +ct = F0278F9EF5B8F9F6F1420253214F91146FA49B552E0A7DF1BBFFE4E7BDBCDA42B4A3068ABB78CCA18E0BC61DE88E031328ECDE797EB412CA5CD368386A21E789316BADD24A8FA447C95B93B9AA6A9F7427DE3A876E3A04D06FA41A6AF2506CE369573D1CDB06CDBD8766F5DA7C02D6193DDA18F2D6DF6CA90058BB9AD102B8920121D0498C74F7CD1B919FC13402ADD606B16D390128336A7AF30CC63E720C0F3F4AB369A0930893184405833B14121CFC0690B3B964D88A62146A2BEBF5F5F3A3A38B7FE2E07A01014D7C57FFE0DDFEF0C152FBC3E10E2E105A28390E93B398C3AC8C79490FF2801529AAA483414FEC8EB28D999428D48A45CC5CF6AFBAE2759D9701986A644BDE7B5FF5AF69ABB80D7404A4008168E966EA02DFEFB7DF1066D4CFDEA4770291A9B4341F0CA346816A703EAF6125BB463ECA61CD73F9E65B20AD18A5129F4695EE00A6883406AFC625C66D72285B8D5AD153D427877DB56864D3786B54C23919AEF60F018D339E63A7C87ADD8CA1639D3320236D3093917269163E2F027025AA01DE59657BC397956122987FEE1B9DA3B94D1210E2CA7F845DCE3F0B0D2730B68D712C5FB2CEB660D8B9D2CD68C9EA5B2BDD7579B26625420801CB027E4C646BA8B4094E5800435B89E0B217DE85500BCC40D503CEBD0752A063CB48AB55371A5D1334EEA93CAA1182D676F2C523AF2E9A259611989AC2BD48162F10A3E313E4B12D8DFC375FBE30C5F77BE65E876965850FF96F32BE1802A4A1D82E97FE8AFDB53EE50229618BC13A4E63894BE22FC545BBDA4059FE6675BA76702DEF3993E94E8BE9048E4030C619166D7A8A +ss = 1CE301DB31CAF217E8F86F2C4DE763B97AEB7A2D72064CB63A5569E5C713D54B + +count = 96 +seed = B3AC6503206ACCC2A92CBC210D020A2654726911D11CE676AA04FEAA08AF1D20C654E4105883AE470EC3AB299075D420 +pk = FC37F83331A63916EC11797513CA32F0A6549012F07BEE7162C4A06352885C0F8A56F74745CCCE89E027C8466DEA7EDB747D8EF60FDFB90EAECBBDCF41D14EF9EA8C70FE436A85126735DC0277E0EC30E84D1844D930BA32BEB3EAA9122E327B5AEF76F277DC00AD148DE1072C6FD51F7CB68589893E97257390FD78FA65502A7F47C952DFFA97CA51B8406DD949C94EB133154A6029CCCBB3966F8271F61B06CAF6A446C66EB872503111AFCCCD966BDDE520E4B537619399FB2C10208936A201C0084341A2E505F0712BAB7683EB9A0E521A8F34BD16C2B11A5C0E12A5B49E038059E14A573B032E923E46C8A667845821F4B7AB1124C441FDE54F7F85B9E7322B3BD9590D09820E9670B94304330D6AFC31C70D35525A8E6BA0238376B04A2F245FB1D02A3A7DFAC6280706E049DA5ABF9F8C07ED31E5DBC9AB4C38D6954C206361722E63D2EC91DE02C3BE2454D36E214F3068F4C37172528EC610E7D5DCF6092456E289BC924CCB6ED489B45964E0F03524CE97F315B41BBFDB1F0916EF321C84D8AF4A9CEB6B5CD0D9369A616B12678FCBA937F805D06AEA6F46C6C7EE51068DBEF43D4CA27D3C68C514307898F5A20E509E8898F803384B5E11B99B8944BD1CD14154A02A4DFA89F7663ABF612B8E0DFADF2BF1ABF09F761620D73B079AF8C83772A675325640849341B389A0AEE65FAA87FE883759C50AF8699347CB0B6D9C69F82247FDD0EE2F5FF08D9309BBB8CDFEBD255AFE6866AF77D21C98B942370DE12462886C95271FF18CF274398329D022 +sk = AC6FCFAEEEF795B6EF9E062F02BF42975FA01E7D91BA832F74E05269A72684D05AEDA108EA4D6C6BC0FB958286850422BC357CA67B83C986048E0D0087FA11EC67FDC3F209B930E1FEF9E3B9A0778802FC37F83331A63916EC11797513CA32F0A6549012F07BEE7162C4A06352885C0F8A56F74745CCCE89E027C8466DEA7EDB747D8EF60FDFB90EAECBBDCF41D14EF9EA8C70FE436A85126735DC0277E0EC30E84D1844D930BA32BEB3EAA9122E327B5AEF76F277DC00AD148DE1072C6FD51F7CB68589893E97257390FD78FA65502A7F47C952DFFA97CA51B8406DD949C94EB133154A6029CCCBB3966F8271F61B06CAF6A446C66EB872503111AFCCCD966BDDE520E4B537619399FB2C10208936A201C0084341A2E505F0712BAB7683EB9A0E521A8F34BD16C2B11A5C0E12A5B49E038059E14A573B032E923E46C8A667845821F4B7AB1124C441FDE54F7F85B9E7322B3BD9590D09820E9670B94304330D6AFC31C70D35525A8E6BA0238376B04A2F245FB1D02A3A7DFAC6280706E049DA5ABF9F8C07ED31E5DBC9AB4C38D6954C206361722E63D2EC91DE02C3BE2454D36E214F3068F4C37172528EC610E7D5DCF6092456E289BC924CCB6ED489B45964E0F03524CE97F315B41BBFDB1F0916EF321C84D8AF4A9CEB6B5CD0D9369A616B12678FCBA937F805D06AEA6F46C6C7EE51068DBEF43D4CA27D3C68C514307898F5A20E509E8898F803384B5E11B99B8944BD1CD14154A02A4DFA89F7663ABF612B8E0DFADF2BF1ABF09F761620D73B079AF8C83772A675325640849341B389A0AEE65FAA87FE883759C50AF8699347CB0B6D9C69F82247FDD0EE2F5FF08D9309BBB8CDFEBD255AFE6866AF77D21C98B942370DE12462886C95271FF18CF274398329D022 +ct = 121855DCA45A42006F934DE3E00D481373DEF60AC619166CC412777D7770CE1BF93B40C65B78C5470DCE4988DA3437839F5C550E7E04E90870C207BF1D2A4F681ABA1111CED2A3879B4E6B7CFC287625C585772DA5070DEC1192BFAD740D5B41E9C3379297D0BA852CBF06F93D8B664725900D5D1C29094D2750CAD10176B9316D5A979B60E6134EF31E9A8FA0AE1C0A71F0A8941D336ED3FD7422A26E981304FB71054663386AA8E71F1947C94087D6B8721F415198C03F8BAA0F6B65E7325CCE9CD6C8B95F8E5C2EA9521459D7448C6B9135BA06F62D06AF96189C0375DD03CAE6C71236A187573D8CAF453BF79C9718B3362F2BA5FE60EF9EA71F9940BF743E61041A1BEDC4A70C95B0F9A1C2E485D39C6E5C9D29F8B3892E32F2B7E2A23217645BCE131E8E5A38F5EF408CE3FE700AFDC99BF2823AD8B721CFB98BDC27096123EB2F1D82D75170B507FDCE783D1B03A153F83FFE0A6CBB6D542AD605E55E6764AF07EE249DD8CC760B4EE8D9EDCC6E9F0C9A701B5A207E1288597A78016F116F646564000B39291DE681DFE37C0CBD95628609AFCD3051F0114103E50341AA9AF9BBDC3171AB91966993D5B726AE81502D6FA0B101ECF2D4EA502325DFCEA3D80FCFA1AF2A39EF3D3C8946FB2ACE99C2731F252C9D07FCB75AB2381EFAF1AEA83A2C8AE3C70A55906C25C21F8A0E7D5128864721306F47F85BBE1DF83DB03BABF31B78DC50DA42FE60BD238D7815299198501FA6C67C865D4CC6D0164CAC1D245BAC2B165215777AF85832C8788252BDCE4A6B3FE2B7AD346F1149388CF9412174EE1700913C36DC7BB11DEF0112952D3D0C +ss = 6D33FE9327795188EF4404E03A913F58918AE8A29C34B28C9124B4689E2E63A7 + +count = 97 +seed = 59EFF60B1EF6185DB34EE1E3B1DD2F159106CECEAA79BEB74923B4F5623D5BC52DBF5D2594A1F7C6C64D12CF144E9ED4 +pk = A38493B1BE7FDC1D69AF4013CFBA79F738EBD22A075F2D405DA8054B47912801111D72959C169E66D88431976569119869FAE3015EA79B3AEB1895BE5CA69FB6E87E4074EEBDD646C3EE6C860F12B57D09FC16F895F976672D7A7F58FA52E4538A492694B46A1F6ECA4519F9348F21196A5C132581ACE888323341E83EA44599FDF05B2998799B96CEEC04441A5786E7BC6352B7A0AF9078D9901091AD5DEF1617A74A080BCD9CF5194FFEC0C5E5AE7414AFF8B6D15554FA649CCC508CE7FF1BC088948B38FBCF59E8FAEEE324D974EFEC182CF912DFCD07BC406806EB7532DDB547A159CF2E86E1178DDBD3D6457B35B7F580ED518EFBA5F51F9E132A27BA7D6651FB24526DB86601ADB5E3A05105D320DC8671A1C5E0A0BD686B348520D96EA0DAC511FEDFA9AEB35E83508EE03F8E4A411CB57C515A0C84EC764347DCF683DFEA55063C7671E0D078BFF5012BC9701547441D2DE82658A6A41389EB175FC144EDF58F7564806D4546A2B5E4EDB565893E83198501E1272B3CCA57783FEEE4AB54C5BFBB21A8265577C119793037A4170D8863597291AE649DD2B8702FA09AFEFF9B610BDC9E9481E7203D0F8D4BDFA1155A6F0D8B03FEAAAF5DE170B9A0C78F7F0375D189D6CC8C54CEA71203A02715F330C6F40836E2994D875B73E13F440D9D19B7F5F06AF1C43C32A00BAB865169D6BCBA3F0F765E496DCB29D965DBC93FADA33C92C7FF49D7E5FB01D8B590F451C2D48252350C44A826AE64DA76A0624DFD6F73F15DF28C47B5E5B280A584A0E376A444 +sk = BA2FB9318D4DBE7488057C33E95E6F054583A2800C41BB83083C330A914A12CFE63F8FFDA3565C2424C89B20974B748A65A5ABA75133FCB3156DFB6626A83BABDA6C8966F6CDEA65916F5EB3C99F9E00A38493B1BE7FDC1D69AF4013CFBA79F738EBD22A075F2D405DA8054B47912801111D72959C169E66D88431976569119869FAE3015EA79B3AEB1895BE5CA69FB6E87E4074EEBDD646C3EE6C860F12B57D09FC16F895F976672D7A7F58FA52E4538A492694B46A1F6ECA4519F9348F21196A5C132581ACE888323341E83EA44599FDF05B2998799B96CEEC04441A5786E7BC6352B7A0AF9078D9901091AD5DEF1617A74A080BCD9CF5194FFEC0C5E5AE7414AFF8B6D15554FA649CCC508CE7FF1BC088948B38FBCF59E8FAEEE324D974EFEC182CF912DFCD07BC406806EB7532DDB547A159CF2E86E1178DDBD3D6457B35B7F580ED518EFBA5F51F9E132A27BA7D6651FB24526DB86601ADB5E3A05105D320DC8671A1C5E0A0BD686B348520D96EA0DAC511FEDFA9AEB35E83508EE03F8E4A411CB57C515A0C84EC764347DCF683DFEA55063C7671E0D078BFF5012BC9701547441D2DE82658A6A41389EB175FC144EDF58F7564806D4546A2B5E4EDB565893E83198501E1272B3CCA57783FEEE4AB54C5BFBB21A8265577C119793037A4170D8863597291AE649DD2B8702FA09AFEFF9B610BDC9E9481E7203D0F8D4BDFA1155A6F0D8B03FEAAAF5DE170B9A0C78F7F0375D189D6CC8C54CEA71203A02715F330C6F40836E2994D875B73E13F440D9D19B7F5F06AF1C43C32A00BAB865169D6BCBA3F0F765E496DCB29D965DBC93FADA33C92C7FF49D7E5FB01D8B590F451C2D48252350C44A826AE64DA76A0624DFD6F73F15DF28C47B5E5B280A584A0E376A444 +ct = F5B0D6E539CD53780DF720072105030BA5EFC6762D2AB2DE874E9B0A414E3DA8C6D621631802117225169E40E54285223B360E55B9CC49C3285701A81F974D300FECEC701DECE4DE87BEAADB39717D1011D5FDD4100BED6C601F43E816515A9D91FBFF90FD1BDAB7E1BA4007C699C1EF1F79EA9392116B33523050783693456871EC8CB10A4C25A594900C031E61273ABDB1C3AA4A98360135B6FBE601928B8C85354002A3ADF7CF74913B0F2E1AAD80D6D850BE893271EE147A6C4774ABE747112F93D0D79DDDA9BDE940C61230452C3A82D6E379CADC87273127E540444CCB3A43EAD1F6E90BD8B6B6B0BD8BB71EE274B91A2F3A444B16134D64D45B9E56816A94369CB07156E71D6937EE8D196A29CA77B1ECDBCBF2C4DD681D0E7E8D9E3586385D1A7461708C0FB5490514D4B88812392D48B86A1B6711C8A5AF16BC18E51FAD7F191459F0FB81A5C1A2C59C57F7CA3E0C813D490EA2DDB3675A0949E34F9F400A736C7322099628CAC796646CDD64A50369128B4906B09F907B341594F51A8A910B5B7515E745FB81926E34697415F9A91904A7705B6C7DE14C5521FEF39CDB5783DBA07BE1217ADED977C7E20CB83871F823D7E9058A5A98E78917EA6C1B5EECDC9F5ED4675FFF48E404AEC1468D54A90686237657FC04B0821E3BACDBC0A71F504EFEBB3564C435B4E04BEA19529C915DAF5134F143F901E499B02CB1EDB24B51FD7D5640F555C3452832593EB2FA6FD52E625B4738BBC3EF1CFECF8AF67255905789BC2BDE252D3E5CAB16130943781CBF82C3DDCF0BB733AB18CEF1214844CE0F7BCDEA9FF74E23E82FC50C62E0AE30 +ss = 864742A6F00FCB874217B6159D2090F8C7F45092337EEB3D9185C72429CDD5F5 + +count = 98 +seed = DDDCA9DC31BEA737D3F474E7560B37FACB2F53C803E768FFAADE7669FF94B1D4FBD17068CFFD5DFDD24AADADA4EF6B12 +pk = 89F9A4D500A4ED8541D5DFC8E380F56DF3A404BA93FAAC39A1DDC82E5C76BB8381623BAEFF4DC1C005ED6E7E8AC8A7E3A281C75A015EE3DA6D4A26C9F7747D2F824F03862308AD5DDBF0852835572C1CA4943C9C0E599417905AE2DACD1165C91981526C8AEE0B43297FC6636BBD854D9594D9B58B134B9FCA366C112B19D226937B809C90776011434F56F2CB99611577D3C137A1D6FAC294DA0223E06A32A59921F91B836EDA78793427889AE27435D050EAB7E0C83B2700AA2004DA694B93EDF279978E575FA2A044B53CFD4BC2A4437849099B305AFCF17CB23999E7FE61FB0010E4DFC51EE28B8D9EEA12195443713DD218E367D8DD7D6A366466B175130BD911992638A283B7318F2F4CFDCF328254B747C1CBF8BDC641BD9B158BA9C308BEEA1D37D62CAB0DB351E025DD467CBB205CEB3C7C179C10E0CBB11BEA1963292BD000D53035180F137EC586BFCE4E508AD9E5AE50714E8099688D227A85C4ABDF895281C8405F02B14D8014C50E1E4C3B3F5409144612A3CCC7AAC2BEDC7D1119B0B488665171AFD7EBC5A088B3C100E052413DAC7E5974C128FAFA50AFE4579355C605BDAADADB7F611B120A4C19BC6364FD3BB8C7893182F5DAAA599C3EF65577A05D3600A03C104FC838CEA7E0A7C4559D7A5156CDF74E5EA0046115F4FF31FBA21F9C2DB13DA08256DFE85DB1DE35C4A2863D9A42523AABA8E1A7FD7C2BE3B43041E2AB2EB5A68B402F4FAD50F3EFCE132ED9C6E824B0F9A869155DC7C4DAE275BDCC4B29D03DEC2F5356588E7D78504C +sk = AA6DD1E5799CDF7AF9C4FC632B3EB9D51D66E85C8E0A21EC98664FC51AB63C7DFDA268813EFAB5204EFA60F78BF81D320D01AC09AC06244F7AFBD2D80FD356D9B7FD18E7550346EDFB273F1506762A0389F9A4D500A4ED8541D5DFC8E380F56DF3A404BA93FAAC39A1DDC82E5C76BB8381623BAEFF4DC1C005ED6E7E8AC8A7E3A281C75A015EE3DA6D4A26C9F7747D2F824F03862308AD5DDBF0852835572C1CA4943C9C0E599417905AE2DACD1165C91981526C8AEE0B43297FC6636BBD854D9594D9B58B134B9FCA366C112B19D226937B809C90776011434F56F2CB99611577D3C137A1D6FAC294DA0223E06A32A59921F91B836EDA78793427889AE27435D050EAB7E0C83B2700AA2004DA694B93EDF279978E575FA2A044B53CFD4BC2A4437849099B305AFCF17CB23999E7FE61FB0010E4DFC51EE28B8D9EEA12195443713DD218E367D8DD7D6A366466B175130BD911992638A283B7318F2F4CFDCF328254B747C1CBF8BDC641BD9B158BA9C308BEEA1D37D62CAB0DB351E025DD467CBB205CEB3C7C179C10E0CBB11BEA1963292BD000D53035180F137EC586BFCE4E508AD9E5AE50714E8099688D227A85C4ABDF895281C8405F02B14D8014C50E1E4C3B3F5409144612A3CCC7AAC2BEDC7D1119B0B488665171AFD7EBC5A088B3C100E052413DAC7E5974C128FAFA50AFE4579355C605BDAADADB7F611B120A4C19BC6364FD3BB8C7893182F5DAAA599C3EF65577A05D3600A03C104FC838CEA7E0A7C4559D7A5156CDF74E5EA0046115F4FF31FBA21F9C2DB13DA08256DFE85DB1DE35C4A2863D9A42523AABA8E1A7FD7C2BE3B43041E2AB2EB5A68B402F4FAD50F3EFCE132ED9C6E824B0F9A869155DC7C4DAE275BDCC4B29D03DEC2F5356588E7D78504C +ct = 7BFA487B6FE9E6788E49F1984E5DADFFEB82B61DA68AE74B66CC3F0B53AFB306936BD124966FFF9EFD8C61915AD84DEFFF7F3200D8AA5D6A03299814FD2D6FE7C2FDC97B104C89A44A7FA09C04A3B29126131A402AADA5EEE44D293F40189301A5F4DFB32C0CDF3E72334ADB5BEF76A7A4C63007E3CEA3A5BFC0BE6BDD53F936BAF8FD65F0BBBA033CA02C9D51696343FD4EE82C1DE1743E14F82BB25E2F958BC308B6A4C515624D6093A875627A3A315EFB18E652BEF26668092E374FA728B2C7C4883E10668BC7C860CD08449C4AFD4632B5AA8BBB10E04961918154B2314F38378497299338F15157469150FF94EBC402C4B965A874F624A7158317618CF7B5697BDA8ADEDDE9D6BEF9539A06836A280F6904D400CCD58A3418606CA972F98F596B8A20CC3C00AB088B8BD091E382AF7DFC1369EBEECB4DB7A5A180247905CD5E3F928816D4F4C380577943F0EDC72892248958DF2D1CA6090BCC2BE68CCE8D1BB78BC25A2815573C98E652767C3BCE3CE4587D24B16BC8C60A96002DB06596748586BC819E00CA352B42D6C888FBA87359670D8013A9BC85249C4BDE327C3F80A3CFCC08772506843434C000A70A99015D9A25FED454F08D30649F9424C8A58A695D11A94C63FBEB36B08DE07B8BC35FAD81C71485F377E70F741401FB5766889ADFB9D32FA9CCFFDF20C413F978F5DF6B8B9C69299ED7A10FD9DB2AB1FA891E668647720FE4D2CA9D167724842D53B6587951624DFDA3940B7515A2F17A7D153AC72C355FB1AA7F8E6E577B5EBA4C3F4A5F2A8F887690E75B0897B50AC2340827590BBC7EA13AECFE62C2C08C12DB5F237A +ss = 5CA7F1A531AA82BBF918A7C07F7F155D83E94EFBF4ED58EE7C0E89ED6C80F2C0 + +count = 99 +seed = 2A6F7386B815366F572AEB6C79E272CC21B7095FE09575F18072C9D677DA23BC9C8A4BC393B7524604D299BEDD260C8B +pk = EBAA29717EAAD6E420FE6D421DC5280A5EA3508170512C0AAD4031CC83D246FDA49AE5DE2E07323AB710FF7BF47BD9C1BDBC5E4D7C94B6739239B9015FD16020AB8384C2C942A0D17B215E95FD9C950B2B7FB65435E1ADD129F9429C7A286E3FD8185342D2AE2158B41C5B0CAFD9A690146F92831C9513961A722852E27722FC8DDD83A1E2AF83712E6467496AD1EB79530BD1C80E1307DBD588685C8958E619937EB5FC5DBDEF739476E4BC05C14FDCFF57A94304071138983A810194E4D2842CBB7615AA4A218E1FA13BFC9D96A73EFDF575410B5A95915DA9D5C4C60BFDFA5B0B027C256454FC4443E090E78B55698A23F8FF1719BEE5A6EB743B3F44D6616B2D89B585DF0FBBAEBAC66D5D360D0C35DBC5406C2386CD9E315DAECA8225B72FA4285D8E3FB28A98A04E1020B8283CFF3C1B68140D335511008EB356E29EC385B371EEF97F8DD4EA31F6CEE7739F8A52E32E5DC6BFA21D98A16BA339831DD85F6C7BD8285B9327FC076E5F1807CD8650D2B038EFE10F066BDE2E4A2A4F923F5DB975EE9C004DFEFBA1185B56C8E3CE45C89DC0178F111823D61CC5DEB69450B9B2B67B84EA05BA7D203A6894AD69BA3B967143B9CEF16786338ABFBA5EC3BAF87EFF76FA3BEA43E48BF22586D1F29378C15917A94E00789093444377566F50CF25E814291BB2DBE132FEDEAADD2DB16F9A8006BF755840613B805238645DBBB1C3F342FA31EC2F7F9821EEA1BC4D41202BCFF2183196002D3793315A6A1510157070149DF48AEF83E290040F8D9AE49EC31F03 +sk = 195D6C86A3DF4C21E3007D7F2768B43C74CB3060E0ECA77F0A5D3271542B9A84AE77E0F9F21EABD8C0C6EEA7767F4E10FDE5C2D79B8400BF96B19014B457EC21CB84E70A7F05DEE947808468042CE102EBAA29717EAAD6E420FE6D421DC5280A5EA3508170512C0AAD4031CC83D246FDA49AE5DE2E07323AB710FF7BF47BD9C1BDBC5E4D7C94B6739239B9015FD16020AB8384C2C942A0D17B215E95FD9C950B2B7FB65435E1ADD129F9429C7A286E3FD8185342D2AE2158B41C5B0CAFD9A690146F92831C9513961A722852E27722FC8DDD83A1E2AF83712E6467496AD1EB79530BD1C80E1307DBD588685C8958E619937EB5FC5DBDEF739476E4BC05C14FDCFF57A94304071138983A810194E4D2842CBB7615AA4A218E1FA13BFC9D96A73EFDF575410B5A95915DA9D5C4C60BFDFA5B0B027C256454FC4443E090E78B55698A23F8FF1719BEE5A6EB743B3F44D6616B2D89B585DF0FBBAEBAC66D5D360D0C35DBC5406C2386CD9E315DAECA8225B72FA4285D8E3FB28A98A04E1020B8283CFF3C1B68140D335511008EB356E29EC385B371EEF97F8DD4EA31F6CEE7739F8A52E32E5DC6BFA21D98A16BA339831DD85F6C7BD8285B9327FC076E5F1807CD8650D2B038EFE10F066BDE2E4A2A4F923F5DB975EE9C004DFEFBA1185B56C8E3CE45C89DC0178F111823D61CC5DEB69450B9B2B67B84EA05BA7D203A6894AD69BA3B967143B9CEF16786338ABFBA5EC3BAF87EFF76FA3BEA43E48BF22586D1F29378C15917A94E00789093444377566F50CF25E814291BB2DBE132FEDEAADD2DB16F9A8006BF755840613B805238645DBBB1C3F342FA31EC2F7F9821EEA1BC4D41202BCFF2183196002D3793315A6A1510157070149DF48AEF83E290040F8D9AE49EC31F03 +ct = BB9AD34AE1A18B4DB7C95D6C3731576C20D613A40D49081FA42F8C7FC42A6392608DA514AAAD5A6FAD4D5757F88EB8F2C29391D09F1080D181347F2624861F41BD0CA1723A389124A51023F65D3D61B358EDD73626A2685E48010381AA3E333AC2454BA71255DAD0939CFDCC83C22BB0E75FDC27C0CE34B1D3660AF8FBFD658703FCA2361E7A1BA6246BC86B9A01C9EAC6F1F0841BA80318392412CB79A98062B8F6FC69F4EBA2C255406DC3FDC98D2F19989D5CA4FF368D784075262F9C6BC82D3D9EC0DFDF85625A3668D26107A0286899A7DF0A900BB994A22CB3A0799CACD5799FCB57AA1265B38DB0DDA5B6E534F4A1484DD8ED6E470DDBD0C124067A28C0BCED38D03A417FA5D93BEE3633EE086E31247975CE68A7BB49C5EC5F4BD399F5C846E3DE49694190B0F6AA64D75971B41F6E90EA738EF15409813FFA666B878E4E1C503287B6F9E5BC5D3566AAF532EA1145AD44E8C5DE3263121F06262666F357452D1B236DED751971DEBE588022CF92981424E108050A6611B8D1FDBC1CBAB5E90AE4865B35D05424A3059E8BB25A13A32FF5A847C700D640DAF47F1B7FC577D6E188A39FBA43661F2586A0CFC80C95DC7D2563FF298F833911D771E09B521465A06CBD45A336190D8A0FB27A8018C2C549DE45B5E361899E6133FC5863BC404EEA67ABCB285044BD6BE2128CDE3F53B7FD5FD0646D5CD82A03F763A98EAE9AA585D9DF8A6CBCD3F70AA2A734256BB659578110DE135CF18523FB0E5A6BFBCE80D6D854B25E1CA4CFEEDAFB74AD4FDEDD348DCE502CB0241D44EE4D6CB56B694BD03D725ADFD7659385645B1467401473A5 +ss = 8ABCE489762C5BBC4C2326539BDA39B08CDE688D81EC4F75F11946550E603D57 + diff --git a/go.mod b/go.mod index 4f6215d..bc8a5eb 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,7 @@ module github.com/henrydcase/nobs -go 1.12 +go 1.14 -require golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e +require ( + golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e +)